2011-05-09 148 views
13

我有一个需要阅读从1gb原始文本文件从磁盘到RAM在C#中做一些字符串操作。C#非常大的字符串操作(内存不足异常)

string contents = File.ReadAllText(path) 

抛出内存异常(不出所料)

什么是去了解这一点的最好方式吗?

+4

什么样的字符串操作?在任何特定时间只阅读一些部分是否可行? – 2011-05-09 22:10:55

+0

理论上是的,但工作瓦特/遗产代码,我知道这将被使用的环境,它会更容易阅读一次去。 – 2011-05-09 22:12:55

+0

我假设你在PC上有足够的可用RAM,你正在尝试使用这个RAM。我知道修改遗留代码可能是一件痛苦的事情(如果它的任务至关重要,那么可怕也是可怕的),但是您可能需要考虑一次只阅读一个块并以这种方式处理它。 – 2011-05-09 22:19:55

回答

12

可能尝试也看看使用memory-mapped file

+0

从文档看来,您会使用“MemoryMappedViewStream”,然后拉入一些字节块。如有必要,请使用'Encoding.GetString' [http://msdn.microsoft.com/en-us/library/05cts4c3.aspx]。 – Dave 2011-05-13 14:25:07

0

如果别人建议的解决方案不工作,我建议你设置字符的限制阅读,阅读文本按部分。一旦你缓存了一部分文本,你就可以操纵它。

如果需要在任何方向操纵它(我的意思是,不从左至右在一个步骤),你总是可以实现在节点:)

一个B-Tree和存储部件的文本有时,按顺序阅读文本几乎是不可能的,这里就是B-Tree的帮助。我大约一年前为了学术目的(微型数据库管理器)实现了它,但我认为应该在C#中实现它。当然,你将不得不实现如何从文件加载BTree的节点。

7

如果你真的想这样做在内存中这个巨大的字符串操作,那么你是不是运气不好了,只要你能满足下列要求

  1. 编译针对64位
  2. 在x64系统上
  3. 运行
  4. 目标.NET 4.5

这将解除您面临的所有内存限制。您的进程内存将仅受计算机内存的限制,并且从.NET 4.5 for x64开始的单个.NET对象上不存在2GiB限制。

0

我对109 MB文件使用ReadAllText,并且内存越来越奇怪。无论如何,所以我使用缓冲区来读取性能良好的文件,并使用StringBuilder来提高内存的效率。 这是我的代码:

   StringBuilder sb = new StringBuilder(); 
       using (FileStream fs = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
       using (BufferedStream bs = new BufferedStream(fs)) 
       using (StreamReader sr = new StreamReader(bs)) 
       { 
        string line;      
        while ((line = sr.ReadLine()) != null) 
         sb.AppendLine(line); 
       }