【问题标题】:C# 2Gb file is 4gb in Ram. Why?C# 2Gb 文件在 Ram 中是 4gb。为什么?
【发布时间】:2013-05-08 13:33:06
【问题描述】:

我正在读取一个文件(这个文件由一个长度为 2gb 的长字符串组成)。

这是我的函数,它将文件的所有内容读入内存,然后拆分字符串并放置: *reader = StreamReader

public List<char[]> GetAllContentAsList()
        {
            int bytesToRead = 1000000;
            char[] buffer = new char[bytesToRead];
            List<char[]> results = new List<char[]>();

            while (_reader.Read(buffer, 0, bytesToRead) != 0)
            {
                char[] temp = new char[bytesToRead];
                Array.Copy(buffer,temp,bytesToRead);
                results.Add(temp);
            }

            return results;
        }

当所有数据放入 List 时,它会占用 4gb 的 RAM。当文件只有 2GB 大小时,这怎么可能?

*编辑

这就是我最终要做的。我没有将字节数组转换为字符串,我只是在操作它们时传递字节。这是内存中只有 2Gb 而不是 4gb 的字段

 public List<byte[]> GetAllContentAsList()
            {
                int bytesToRead = 1000000;
                var buffer = new byte[bytesToRead];
                List<byte[]> results = new List<byte[]>();

                while (_reader.Read(buffer, 0, bytesToRead) != 0)
                {
                    //string temp = Encoding.UTF8.GetString(buffer);
                    byte[] b = new byte[bytesToRead];
                    Array.Copy(buffer,b,bytesToRead);
                    results.Add(b);
                }

                return results;
            }

【问题讨论】:

  • 如何得出这个 List 占用 4GB 内存的结论。单个对象限制为 2GB。你明白Array.Copy(buffer,temp,bytesToRead); 行会继续消耗内存,直到垃圾收集器决定在你之后清理,对吗?
  • 你可以在c#中使用4gb吗?
  • @Venson - 在 64 位操作系统和进程上,当然,为什么不呢?
  • 就像 Oded 所说,char 可以大于编码后的 byte(s)。为什么在您的代码中随意创建List 和过多的数组克隆? Files.ReadAllText("yourfile").ToCharArray() 似乎是等价的。
  • 这是一种非常糟糕的数据读取方式,顺便说一句;使用流式 API(或基于阅读器的 API)会更好

标签: c# file filestream textreader


【解决方案1】:

这里有根据的猜测:

该文件采用UTF-8ASCII 编码,并且仅(大部分)包含单字节宽的字符(或可能其他一些主要是单字节宽的代码页)。

现在,.NET 字符为 UTF-16,长度均为 2 个(或更多)字节。

因此,在内存中,字符的大小将是原来的两倍。

【讨论】:

  • +1 通过在保存文件时更改文件的编码来轻松测试。
  • 大概就是这样。 Char 是 16 位(2 字节)。
  • @slugster - 当然可以,但是有一个 2GB 的文件,我会留给你测试 ;)
  • 另外,如果我记得,Array.Copy 本身可能会影响记忆(尽管更多的是在工作过程中,而不是最终结果)。
  • 酷,感谢您的快速回复。我试试看
猜你喜欢
  • 1970-01-01
  • 2010-10-16
  • 2014-09-12
  • 1970-01-01
  • 2012-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多