c# - 读取和修改 3-5GB 的大文本文件

标签 c# filestream streamreader streamwriter file-handling

我有一个包含几百万行的相当大的文件,需要检查并从文件中删除损坏的行。

我厚颜无耻地尝试了 File.ReadAllLines 但它没有用。然后我尝试流线如下所示从原始文件读取并写入新文件。虽然它完成了这项工作,但它会在几个小时 (5+) 内完成。我读过有关使用缓冲区的信息,这听起来像是唯一的选择,但我将如何以这种方式保持线路完整性?

解决方案: StreamWriter 移到 while 之外。不使用拆分,而是使用计数。

 using (FileStream inputStream = File.OpenRead((localFileToProcess + ".txt")))
 {
    using (StreamReader inputReader = new StreamReader(inputStream, System.Text.Encoding.GetEncoding(1254)))
    {
       using(StreamWriter writer=new StreamWriter(localFileToProcess,true,System.Text.Encoding.GetEncoding(1254)))
       {
          while (!inputReader.EndOfStream)
          {
             if ((tempLineValue = inputReader.ReadLine()).Count(c => c == ';') == 4)
             {
                 writer.WriteLine(tempLineValue);
             }
             else
                 incrementCounter();
          }
       }
    }
}

最佳答案

我认为您的原始代码中最慢的部分是创建/处置 StreamWriter。在每个 Dispose 上,StreamWriter 必须将所有未写入的数据刷新到光盘、关闭文件句柄等。在打开的操作系统上必须检查安全权限、当前锁以及做许多其他事情。

当您开始只使用一个 StreamWriter 时,它的内部写入缓冲区开始工作,将数据大块写入磁盘。除了跳过关闭/打开文件进行写入外,还可以节省大量时间。磁盘 I/O 通常是应用程序中最慢的部分。

Split(';') 也可能对速度产生影响,但我认为影响不大。无论如何,在 C# 中应该小心地执行字符串操作,因为字符串是不可变的并且会在内存中产生大量垃圾。因此,如果您可以检查 4 个分号,它总是比调用 Split(';') 分配数组并(在您的情况下)每行在内存中创建 5 个字符串要好。当使用不可变字符串执行大量字符串操作时,即使没有任何磁盘 I/O,它也可能严重影响应用程序性能。

至于在您的案例中使用 StringBuilder - 我认为它没有太大帮助,因为 StreamWriter 已经具有内置缓冲。

关于c# - 读取和修改 3-5GB 的大文本文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17853439/

相关文章:

c# - 如何在 Windows 8.1 上打开多个 Visual Studio 窗口?

c# - 如何将从条形码读取的文本转换为阿拉伯文本

c# - 无法从 WPF 应用程序连接到 WinRT 服务器

c# - FileStream 错误 - 进程无法访问文件...被另一个进程使用

c# - StreamReader 和 EBCDIC 的奇怪行为 : Why?

C# 在 Windows 中重新排列多显示位置

c# - 将对象转换为 C# 类

sql-server - SQL 2013 Filestream 文件组已满,但有足够的空间?

c# - StreamReader 问题查找文件

c# - StreamReader 将 MemoryStream 读取到字符串似乎正在截断文件结尾