1

对于某些项目,我需要覆盖文件,但由于用户可能同时使用其他程序编辑此文件,因此我不会经常在运行时保留流,而是将所有数据保存在字节数组中。保存我的程序时,应该只保存它编辑的区域,而不是整个文件。我已经(非常糟糕)编写了一个例程来这样做,但它预计会很慢,我不知道如何在这里提高性能。我实际上只是循环遍历整个数组,并不像看起来那么聪明:

    public Boolean Patch(string path)
    {
        FileStream fs = new FileStream(path, FileMode.Open);
        BinaryReader br = new BinaryReader(fs);
        BinaryWriter bw = new BinaryWriter(fs);
        if (fs.Length != this.rawdata.Length)
            throw new ArgumentException();
        for (int i = 0; i < this.rawdata.Length; ++i )
        {
            if (br.ReadByte() != rawdata[i])
            {
                fs.Position--;
                bw.Write(rawdata[i]);
            }
        }
        fs.Close();
        return true;
    }
4

1 回答 1

0

您对硬盘驱动器(或任何其他流)的每次访问都是昂贵的。将您的代码转换为使用下一个(例如,1024)字节的缓存副本X来读取,以及Y(例如,1024)字节来写入。

我并不完全理解你的代码应该做什么,但是说你想在流之间复制一个文件,你的函数应该是本着以下精神的东西:

private const int BUFFER_SIZE = 1024;

void copy(BinaryReader inStream, BinaryWriter outStream)
{
    byte[] cache = new byte[BUFFER_SIZE];
    int readCount = 0;
    while ((readCount = inStream.Read(cache, 0, BUFFER_SIZE)) != 0)
    {
        outStream.Write(cache, 0, readCount);
    }
}

在这个例子中,BUFFER_SIZE不要太小(这样批量读写会很有效),也不要太大——溢出你的内存。
在您的代码示例中,您每次都读取一个字节(即BUFFER_SIZE = 1),因此这会减慢您的应用程序的速度。

编辑:添加了您需要编写的代码:

public Boolean Patch(string path)
    {
        const int BUFFER_SIZE = 512;

        // VERY IMPORTANT: The throw operation will cause the stream to remain open the function returns.
        using (FileStream fs = new FileStream(path, FileMode.Open))
        {
            BinaryReader br = new BinaryReader(fs);
            BinaryWriter bw = new BinaryWriter(fs);
            if (fs.Length != this.rawdata.Length)
                throw new ArgumentException();
            byte[] cache = new byte[BUFFER_SIZE];
            int readCount = 0, location = 0;
            while ((readCount = br.Read(cache, 0, BUFFER_SIZE)) != 0) 
            {
                int changeLength = 0;

                for (int j = 0; j < readCount; j++)
                {
                    if (cache[j] != rawdata[j + location])
                    {
                        changeLength++;
                    }
                    else if (changeLength > 0)
                    {
                        fs.Position = location + j - changeLength;
                        bw.Write(rawdata, location + j - changeLength, changeLength);
                        fs.Position = location + j;

                        changeLength = 0;
                    }
                }

                location += readCount;
            } 

            return true;
        }
    }
于 2013-08-05T21:21:43.930 回答