DIFF: 用于远程差分压缩的 IRdcLibrary API






4.11/5 (6投票s)
一个用于差分内存/文件处理的快速库
- GitHub: 我的多线程工具的一部分: https://github.com/WindowsNT/mt
引言
在我看来,你一直都想创建一个具有每个文件增量处理的备份/恢复功能。这是一个小型库,展示了 IRdcLibrary
COM API 的强大功能,随时可以使用。
背景
像往常一样,使用 COM、Win32 和 C++。我在这里不容忍比我更初级的人 :P。
Using the Code
DIFF
库可以从文件和内存中读取/写入。对于读取数据,您可以使用 Microsoft 的 IRdcFileReader interface
。为了您的方便,我在代码中提供了 2 个辅助类,它们可以提供 IRdcFileReader interface
MemoryRdcFileReader
,它可以从内存中读取。在存在此 interface
时,内存必须持久存在(即,interface
不会复制内存)。
构造函数
MemoryRdcFileReader(const char* dd,unsigned long long size);
FileRdcFileReader
,它可以从现有的 HANDLE
中读取。该句柄必须已使用 GENERIC_READ
打开,并且必须是可寻址的。
构造函数
FileRdcFileReader(HANDLE hF);
对于写入数据,我的函数需要一个 DIFFWRITER
类的实例。我还提供了一个 FileDiffWriter
(它可以从一个必须使用 GENERIC_WRITE
打开的 HANDLE
提供一个 DIFFWRITER
)和一个 MemoryDiffWriter
,它写入到一个 vector<char>
。这些辅助类提供了成员函数 GetReader(IRdcFileReader**)
,该函数返回一个 MemoryRdcFileReader
或一个 FileRdcFileReader
。
增量备份
假设您在 c:\test 中有一个名为 1.txt 的文件,并且您已将其备份到 c:\test2 中。现在假设您已修改了原始 c:\test 目录中的 1.txt,因此 c:\test\1.txt 是较新的。现在,您的增量备份步骤是(为简单起见,删除了错误检查)
// Prereqs: file readers for both files.
// Say that hX1 and hX2 are handles to these two files
CComPtr<IRdcFileReader> fil1;
CComPtr<IRdcFileReader> fil2;
fil1.Attach(new DIFF::FileRdcFileReader(hX1));
fil2.Attach(new DIFF::FileRdcFileReader(hX2));
// Instantiate the library
DIFF::DIFF d;
// Create a signature for both files
// Say that hS1 and hS2 are handles to new files that the signature is to be stored
DIFF::FileDiffWriter sig1(hS1);
DIFF::FileDiffWriter sig2(hS2);
d.GenerateSignature(fil1,sig1);
d.GenerateSignature(fil2,sig1);
// Close handles
这会将新旧 1.txt 的 RDC 签名保存在文件中。
您的下一步是生成 2 个文件之间的差异。我的库为您提供 2 个选项:您可以创建一个自包含的 diff
,或者创建一个独立的 diff
。
自包含的 diff
允许您从源文件离线重建更新的文件。
独立的 diff
要小得多,但它需要远程文件的一部分。因此,如果要使用独立的 diff
,您必须自己实现一个 IRdcFileReader
,该 IRdcFileReader
从服务器下载更新文件的请求部分。由于这需要服务器,因此我们将在此处重点介绍自包含的 diff
。
现在,您要创建新旧文件之间的 diff
。
CComPtr<IRdcFileReader> xsig1;
CComPtr<IRdcFileReader> xsig2;
sig1.GetReader(&xsig1);
sig2.GetReader(&xsig2);
DIFF::MemoryDiffWriter diff1_2_sc;
d.GenerateDiff(xsig1,xsig2,r2,diff1_2_sc));
如果传递 NULL
而不是第三个参数中的 r2
,这将生成一个自包含的 diff
(如果传递 NULL
代替第3个参数中的 r2
,它将生成一个独立的diff
)。现在,您可以上传此较小的 diff
文件,而不是上传您的新文件 c:\test\1.txt。它的小程度取决于文件之间的差异程度。
Diff 恢复
现在假设您有 1.txt 的原始(主)备份,并且您想恢复较新的 1.txt。您需要原始的 1.txt 和一个自包含的 diff
文件
// r1 is the reader for the original file.
// xdiff2 is reader for the diff.
// Say hX3 is a handle to the file we want to reconstruct
DIFF::FileDiffWriter reco1(hX3);
d.Reconstruct(r1,xdiff1,0,reco1);
就这样。您的较新 1.txt 文件已通过原始文件和 diff
重建。如果 diff
是一个独立的 diff
,您将必须传递一个读取器到 DIFF::Reconstruct
的第 3 个参数,该参数将被要求提供文件的部分内容。
关注点
- 该 API 需要 Vista 或更高版本。
- 该库仅在多线程 COM 环境中运行 (
CoInitializeEx(0, COINIT_MULTITHREADED);
) - 如果无法创建 COM 对象,则构造函数会引发异常。
- 我必须进一步调查一个相似性 API。
- 该库使用智能指针,包括 COM ATL 和 C++。
玩得开心!
历史
- 2016 年 3 月 21 日:实现为 * .h * 文件,并进行了一些错误修复
- 2015 年 10 月 21 日:一些错误修复和一些实验性的多签名内容
- 2015 年 1 月 6 日:首次发布(新年快乐:))