Nat*_*han 3 c# string file-handling
我想要将150 MB的文本文件加载到字符串中.该文件是UTF16编码的,因此它将生成一个内存大约150 MB的字符串.我尝试过的所有方法都会导致Out of Memory异常.
我知道这是一个巨大的字符串,当然不是我想做的事情.但是,目前我无能为力,没有对应用程序进行大量深刻更改即将出门.该文件中没有均匀分布的行集.一行可以包含整个文件大小的80%左右.
这是我尝试过的:
方法1
// Both of these throw Out of Memory exception
var s = File.ReadAllText(path)
var s = File.ReadAllText(path, Encoding.Unicode);
Run Code Online (Sandbox Code Playgroud)
方法2
var sb = new StringBuilder();
// I've also tried a few other iterations on this with other types of streams
using (FileStream fs = File.Open(path, 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);
}
}
// This throws an exception
sb.ToString();
Run Code Online (Sandbox Code Playgroud)
方法3
using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (StreamReader sr = new StreamReader(fs, Encoding.Unicode))
{
int initialSize = (int)fs.Length / 2; // Comes to a value of 73285158 with my test file
var sb = new StringBuilder(initialSize); // This throws an exception
string line;
while ((line = sr.ReadLine()) != null)
{
sb.AppendLine(line);
}
sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)
那么,如何将此文件加载到字符串变量中呢?
编辑:添加了基于评论解决问题的其他尝试.
到目前为止,您的两次尝试都将文件视为UTF-8.在最好的情况下,这将占用两倍的内存 - 而且很可能是无效数据(如UTF-8),基本上.您应该尝试指定编码:
var text = File.ReadAllText(path, Encoding.Unicode);
Run Code Online (Sandbox Code Playgroud)
如果这不起作用,你可以尝试第二个代码的变体,但是指定编码StreamReader(并且可能忽略了BufferedStream- 我认为它不会对你有所帮助),并且还指定了初始容量StringBuilder,等于文件大小的一半.
编辑:如果此行抛出异常:
var sb = new StringBuilder(initialSize);
Run Code Online (Sandbox Code Playgroud)
......那你就没有机会了.您无法分配足够的连续内存.
你可能会发现你可以用一个List<string>代替:
var lines = File.ReadLines(path).ToList();
Run Code Online (Sandbox Code Playgroud)
...至少你有很多小东西.这将需要更多的内存,但它不需要那么多的连续内存.这假设您确实需要一次在内存中的整个文件.如果你可以改为传输数据,那将是一个更好的选择.
在一个小型控制台应用程序中,我能够读取相同大小的文件,没有问题,使用File.ReadAllText32位和64位CLR ...所以它可能是你的物理内存和你还有什么问题正在做这个计划.