我正在xcopy
使用以下命令行在 Windows 上执行磁盘备份:
xcopy "d:\" "r:\" /v /h /k /e /b /d
我知道验证开关没有多大作用,但是对于初始副本来说,文件大小比较总比没有好。
我遇到的问题xcopy
是抛出文件验证错误,我不知道为什么。有问题的文件是一个符号链接,它指向的文件已经存在。
我有 Cygwin,我在两个链接以及它在两个磁盘上指向的实际文件上都运行了 a diff
,diff --no-dereference
和,没有任何区别。cmp
这两个文件都是 73 字节。
我无法通过创建具有有效或无效链接的测试文件夹来重现这一点,同时使用xcopy
相同的选项在相同或不同的磁盘上执行复制。
为什么会xcopy
以这种方式失败?
Xcopy 在复制符号链接时不记录文件大小,但验证通过不知道符号链接,并尝试将目标文件的大小与(未设置的)记录进行比较。
这可以通过 Sysinternals Process Monitor观察到。一次只复制一个文件并
xcopy.exe
在 Xcopy 询问您目标是否是目录但在您回答之前才开始从进程中捕获文件 IO 事件是最有启发性的 - 这样,您就跳过了所有进程启动 IO。当/B
被传递时,Xcopy 在CreateFile
打开源文件的操作中设置“打开重解析点”选项,告诉 Windows 如果文件结果是符号链接(重解析点)它想要打开符号链接本身而不是目标文件. 稍后,在创建目标文件后,将其设置为符号链接,并将一些文件属性打乱,如果/V
通过,Xcopy 发出另一个CreateFile
再次打开目标文件,但没有“打开重分析点”选项。如果这是一个符号链接,则结果是,Windows 实际上会在接下来的操作REPARSE
中打开 Xcopy 的目标文件。CreateFile
很快,Xcopy 执行了一项QueryStandardInformationFile
操作,获得了它认为是目标的文件大小。但是回顾日志,我们提醒自己QueryStandardInformationFile
之前没有对源文件进行过/通过源文件的操作来比较文件大小。相反,如果您监视普通文件的 Xcopy(即使使用/B
),您会在使用 .QueryStandardInformationFile
打开源文件后很快看到对源文件的操作CreateFile
。为了进一步支持这一假设,Xcopy可以复制并成功验证指向零字节文件的符号链接。显然文件大小记录是零初始化的,所以即使在复制符号链接时没有设置它,当验证通过盲目地打开复制符号链接的目标以获取其大小时,零的答案与默认的零匹配。
该
/v
选项会根据每个文件的大小验证每个文件的写入情况,以确保它们相同。验证从 Windows XP 开始内置于
xcopy
命令中,但在更高版本的 Windows 中应该什么都不做。它只是为了与旧的 MS-DOS 文件兼容而包含在内。难怪这个古老的验证码不适用于符号链接等较新的功能。
xcopy
如果您有符号链接,我建议不要使用。使用可以进行验证的更现代的应用程序,例如 TeraCopy。