Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 读取和修改大型文本文件3-5GB_C#_Filestream_Streamreader_Streamwriter_File Handling - Fatal编程技术网

C# 读取和修改大型文本文件3-5GB

C# 读取和修改大型文本文件3-5GB,c#,filestream,streamreader,streamwriter,file-handling,C#,Filestream,Streamreader,Streamwriter,File Handling,我有一个相当大的文件,由几百万行组成,需要检查并从文件中删除损坏的行 我无耻地尝试了File.ReadAllLines,但没有成功。然后,我尝试如下流式传输行,从原始文件读取并写入新文件。当它完成工作时,它会在几个小时内完成(5+)。我读过关于使用缓冲区的书,这听起来像是唯一的选择,但我怎样才能保持线路的完整性呢 解决方案:StreamWriter已移动到while之外。使用计数代替拆分 using (FileStream inputStream = File.OpenRead((localF

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

我无耻地尝试了
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。在每次处理中,StreamWriter都必须将所有未写入的数据刷新到光盘中,关闭文件句柄等。在开放操作系统上,StreamWriter必须检查安全权限、当前锁以及其他许多操作

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

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


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

请注意,Split(“;”)分配一个数组,并在内存中每行创建5个字符串。这增加了垃圾收集器的工作。也许你应该检查一下你的行中是否有4个分号?此外,您正在创建/处理StreamWriter的每个迭代。在开始时创建一个并在操作结束时进行处理不是更好吗?很好。我会进行更改。将批读入字符串生成器,处理,然后一次性写入如何?@Artemix尝试了您的建议,并获得了5个多小时到15分钟的下降时间。我也要试试行李处理系统的建议。