替换文件中与原始文件不匹配的字节

时间:2018-03-31 12:31:53

标签: c# arrays replace filestream corrupt

我希望通过网络复制最小字节数,以减少VPN上的带宽。我有一个外部服务器,我想备份和复制文件从我的PC到服务器。有些文件很大(数据库备份)。每次发生变化时我都不想继续复制这些GB,我不得不重新上传整个文件。

我比较文件哈希值,如果它们不同,我会找到文件中不匹配的字节并替换它们。以下是一些示例代码:

static void Main(string[] args)
{
    byte[] fileAData = File.ReadAllBytes(fileA.FullName);

    int bufferSize = sizeof(Int64);

    int totalIterations = (int)Math.Ceiling((double)fileA.Length / bufferSize);
    int remainingBytesLength = (int)(fileA.Length % bufferSize);

    using (FileStream fileStreamA = fileA.OpenRead())
    using (FileStream fileStreamB = fileB.Open(FileMode.OpenOrCreate))
    {
        byte[] fileABytes = new byte[bufferSize];
        byte[] fileBBytes = new byte[bufferSize];

        for (int i = 0; i < totalIterations; i++)
        {
            if (i == totalIterations - 1)
            {
                // If this iteration is the last iteration, read only the remaining bytes
                bufferSize = remainingBytesLength;

                fileABytes = new byte[bufferSize];
                fileBBytes = new byte[bufferSize];
            }

            // Save the current position before read
            long currentPosition = fileStreamA.Position;

            fileStreamA.Read(fileABytes, 0, bufferSize);
            fileStreamB.Read(fileBBytes, 0, bufferSize);

            // Check and replace bytes if they do not match
            if (!fileABytes.SequenceEqual(fileBBytes))
            {
                byte[] destArr = new byte[fileABytes.Length];
                Array.Copy(fileABytes, destArr, fileABytes.Length);

                // Keep a collection of all the changes to the file
                // We will serialize and send this collection to minimalize bandwidth usage
                changes.Add(new Change
                {
                    Data = destArr,
                    Position = currentPosition,
                    Length = destArr.Length
                });
            }
        }

        // If file B is larger than file A, remove the remaining bytes in fileB
        if (fileB.Length > fileA.Length)
        {
            fileStreamB.SetLength(fileA.Length);
        }
    }
}

虽然此代码适用于文本文件,但当我尝试在较大的文件上运行此代码时,拾取的更改量等于原始文件的大小。

实施例

如果文件的结构如下:

Original file:

Position:   1    2    3    4    5    6    7....
Byte:       A    B    C    D    E    F    G

Corrupted file:

Position:   1    2    3    4    5    6    7....
Byte:       A    B    C    E    F    G    H

代码将获取前三个字节相同(A,B,C)。 但是当它看到位置4时,它会在其后接收其他所有内容(实际上所有字节只向左移一个位置)。 我想检测到唯一的变化是技术上的位置4,这样我就不必通过网络复制其余的字节了。

我是通过比较块中的字节来采取正确的方法,还是有更快/更简单的方法?

如果文件损坏,是否会重新排列整个文件的字节顺序,导致此方法无用? (我通过在文本编辑器中打开一个mp4文件并删除块来模拟一个&#34;腐败&#34;)来测试这个。

额外注意:我们在客户端服务器上使用备份专有软件,它只同步文件中已更改的字节,所以我认为这一定是可行的。

0 个答案:

没有答案