处理大文件在C#(Processing Huge Files In C#)

2019-07-29 05:46发布

我有我要执行基于字节的查找和替换一个4GB的文件。 我写了一个简单的程序来做到这一点,但它需要时间太长(90分+)做只有一个查找和替换。 我已经尝试了几个十六进制编辑器可以在3分钟内完成任务,不整个目标文件加载到内存中。 有谁知道在哪里我可以完成同样的事情的方法? 这里是我当前的代码:

    public int ReplaceBytes(string File, byte[] Find, byte[] Replace)
    {
        var Stream = new FileStream(File, FileMode.Open, FileAccess.ReadWrite);
        int FindPoint = 0;
        int Results = 0;
        for (long i = 0; i < Stream.Length; i++)
        {
            if (Find[FindPoint] == Stream.ReadByte())
            {
                FindPoint++;
                if (FindPoint > Find.Length - 1)
                {
                    Results++;
                    FindPoint = 0;
                    Stream.Seek(-Find.Length, SeekOrigin.Current);
                    Stream.Write(Replace, 0, Replace.Length);
                }
            }
            else
            {
                FindPoint = 0;
            }
        }
        Stream.Close();
        return Results;
    }

查找和替换使用4GB的“文件”的方式相比相对较小。 我可以很容易地看到,为什么我的算法是缓慢的,但我不知道我怎么会做的更好。

Answer 1:

问题的部分原因可能是您正在阅读在时间的流里一个字节。 尝试阅读较大的块并做了更换的。 我约8KB开始,然后用一些或大或小的块进行测试,看看有什么给你最好的性能。



Answer 2:

有很多更好的算法在字符串找到子(这基本上是你在做什么)

从这里开始:

http://en.wikipedia.org/wiki/String_searching_algorithm

其中的要点是,你可以通过分析你的子跳过了很多字节。 这里有一个简单的例子

4GB的文件的开头为:ABCDEFGHIJKLMNOP

你个子串:NOP

  1. 你跳过子-1​​的长度和核对最后一个字节,所以比较C至P
  2. 它不匹配,所以子并不是第3个字节
  3. 此外,C是不是在串好,所以你可以跳过3个字节(串的LEN)
  4. 比较F到P,不匹配,F是不是子,跳过3
  5. 我比较为P,等等等等

如果匹配,往后走。 如果字符不匹配,但在子串,那么你必须做更多的一些在这一点上比较(阅读链接了解详细信息)



Answer 3:

而不是按字节读取文件字节由缓冲区中读取数据:

buffer = new byte[bufferSize];            
currentPos = 0;
length = (int)Stream .Length;
while ((count = Stream.Read(buffer, currentPos, bufferSize)) > 0)
{
   currentPos += count;
   ....
}


Answer 4:

另外,在每次读超过一个字节更简单的方法:

var Stream = new BufferedStream(new FileStream(File, FileMode.Open, FileAccess.ReadWrite));

与如何读入缓冲区,以及更好的二进制发现之一赛义德·阿米里的例子结合本/替换算法应该给你更好的结果。



Answer 5:

你应该尝试使用内存映射文件 。 C#支持他们开始用4.0版本。

存储器映射文件包含在虚拟存储器中的文件的内容。

持久化的文件是一个磁盘上的源文件相关联的内存映射文件。 当最后一道工序完成与文件工作,将数据保存到磁盘上的源文件。 这些内存映射文件都适用于非常大的源文件的工作。



文章来源: Processing Huge Files In C#