C#解析文件末尾缺少换行符的文件

问题描述 投票:0回答:2

问题:解析文件末尾缺少新行字符的文件的最佳方法是什么?我应该使用try并捕获OutOfMemoryException吗?或者,还有更好的方法?

背景:我正在使用StreamReader的Readline()方法解析日志文件,以便在下一行中读取。所以,基本的循环结构如下所示:

while ((line = sr.ReadLine()) != null)
{
      // Parse the file
}

即使在大型文件(即> 2GB)上也能很好地工作。但是,当下一行不为null并且不包含换行符时,StreamReader只读取空格,直到消耗掉所有内存并抛出OutOfMemoryException。这是处理文件末尾缺少新行字符的最佳方法吗?或者,有更好的方法来处理这个问题吗?

注意:该文件是从IIS Exchange Server创建的。如果没有深入了解我们的IT小组,该文件似乎会在创建过程中被切断,导致最后一行变坏,因为它缺少数据。

研究:我在SO上发现了一个帖子(见下文),指的是使用File.ReadFile。虽然它适用于缺少新行字符的小得多的文件(即<2GB),但它仍然在大文件上失败(即> 2GB)。

https://stackoverflow.com/a/13416225

https://docs.microsoft.com/en-us/dotnet/api/system.io.file.readlines?redirectedfrom=MSDN&view=netframework-4.7.2#System_IO_File_ReadLines_System_String_

编辑

编译器在下面的代码示例中的While行停止。问题不在于代码,而在于文件。我无法发布我们的日志文件。但是,要演示,请在NotePad ++中创建几行数据。对于文件的最后一行,删除NewLine字符,然后运行该文件。 StreamReader将在最后一行爆炸,因为它无法找到行的结尾。

下面是日志文件的副本,其中删除了所有数据内容,但每行末尾的时间戳和NewLine字符除外。对于最后一行,我在数据中断之前包含了最后一个数据元素(端口号)。请注意,最后一行缺少新行字符?

enter image description here

c# parsing streamreader
2个回答
1
投票

这应该工作:应该在尝试读取下一行之前检查EndOfStream。添加了一些null检查。

while (!sr.EndOfStream)
{
  line = sr.ReadLine()?.Trim() ?? "";
  // Parse the line
}

0
投票

我已经确认该文件对我们的IT小组来说很糟糕。发生的事情是,通过网络到我当地的原始转移过程似乎经历了一次打嗝。我重新传输了文件并成功解析了。还有更多行。让我误解的是网络和我的本地文件大小相同 - 所以我在研究过程中没有考虑重新传输文件。

文件传输过程似乎首先将一个完整的文件分配为空,然后开始用数据填充它。祝你好运诊断标准文本编辑器无法打开的超大文件(例如,记事本,Notepadd ++,Excel等)。我不得不使用Ultra Edit,问题变得明显。

根据Hans Passant对相关问题的评论(参见下面的链接),StreamReader的Readline()方法将处理大文件,因为它在内部处理文件系统缓存。因此,OutOfMemoryExceptions应该不是问题。我认为这是针对内存不足而不是坏文件的计算机。

感谢大家的排除故障,并对任何中断表示歉意。

Unable to read large log file with MemoryMappedViewStream

© www.soinside.com 2019 - 2024. All rights reserved.