我希望通过网络复制最小字节数,以减少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;)来测试这个。
额外注意:我们在客户端服务器上使用备份专有软件,它只同步文件中已更改的字节,所以我认为这一定是可行的。