问题:解析文件末尾缺少换行符的文件的最佳方法是什么?我应该只是试着抓住OutOfMemoryException吗?还是有更好的方法?
背景:我正在使用StreamReader的Readline()方法解析日志文件以在下一行中读取。因此,基本的循环结构如下所示:
while ((line = sr.ReadLine()) != null)
{
// Parse the file
}
即使在大文件(即> 2GB)上,此方法也能很好地工作。但是,当下一行不是并且不包含换行符时,StreamReader只会读取空格,直到消耗完所有内存并引发OutOfMemoryException。这是处理文件末尾缺少的换行符的最佳方法吗?还是有更好的方法来解决此问题?
注意:该文件是从IIS Exchange Server创建的。如果不与我们的IT部门联系,该文件似乎在创建过程中被切断,导致最后一行由于丢失数据而损坏。
研究:我在SO上找到了一条帖子(见下文),其中提到使用File.ReadFile
。虽然它可以在缺少新行字符的较小文件(即<2GB)上工作,但在较大文件(即> 2GB)上仍然无法使用。
https://stackoverflow.com/a/13416225
修改
编译器在以下代码示例的While行中停止。问题不在于代码,而在于文件。我无法发布日志文件。但是,为演示起见,在NotePad ++中创建了几行数据。对于文件的最后一行,删除NewLine字符,然后运行文件。 StreamReader将在最后一行上爆炸,因为它找不到行的结尾。
以下是日志文件的副本,其中除去了所有数据内容,但时间戳记和每行末尾的换行符除外。对于最后一行,我包括了数据切断前的最后一个数据元素(端口号)。注意最后一行缺少换行符吗?
答案 0 :(得分:1)
这应该起作用: 在尝试读取下一行之前,应检查EndOfStream。 还添加了一些对null的检查。
while (!sr.EndOfStream)
{
line = sr.ReadLine()?.Trim() ?? "";
// Parse the line
}
答案 1 :(得分:0)
我已经确认该文件对我们的IT部门而言是错误的。发生的事情是,通过网络到本地的原始传输过程似乎遇到了麻烦。我重新传输了文件,并成功解析了文件。还有更多的行。令我震惊的是,网络和本地之间的文件大小是相同的-因此,在我的研究工作中,我没有考虑重新传输文件。
文件传输过程似乎首先是将一个完整的文件分配为空,然后开始用数据填充它。祝您好运,以诊断无法通过标准文本编辑器(例如记事本,Notepadd ++,Excel等)打开的超大文件。我不得不使用Ultra Edit,问题变得显而易见。
根据Hans Passant对一个相关问题的评论(请参阅下面的链接),StreamReader的Readline()方法将处理大型文件,因为它在内部处理文件系统缓存。因此,OutOfMemoryExceptions应该不会有问题。我认为这是针对内存不足而不是错误文件的计算机。
谢谢大家的故障排除,对于由此造成的任何干扰,我深表歉意。