我正在运行一个包含以下内容的 .bat:
robocopy \\server\directory\ .\localdir /MIR
这会将单个文件从服务器移动到我的本地目录。
这是一个很大的文件,需要一段时间才能完成,但我可以使用该位置的现有文件副本来实现我需要的功能。
文件到底会在什么时候被覆盖?我可以通过 ^C 退出并使用 .bat 开始运行之前位于 \localdir 中的文件吗?还是我需要等待 robocopy 完成?
答案1
robocopy
与任何其他文件复制程序没有什么不同。覆盖复制会“截断”文件中的现有数据,然后开始写入新数据。您可以使用监控 robocopy 调用的系统 API 的程序来观察这一点,例如列出的选项之一这里然后您只需要在 MSDN 上查找每个 API 调用即可准确了解发生了什么。
首先,它调用设置文件指针定位到文件的开头(如果文件还没有开始的话)。然后它调用设置文件结束符将文件截断到 BOF 标记(使其成为零字节文件)。这一切发生得如此之快,以至于一旦此命令开始执行,您的原始文件数据实际上就“丢失”了(表示文件数据流的块将很快被未来的 NTFS 写入命令全部或部分覆盖)。
如果您想“原子地”执行此操作,您可以执行重命名操作,如下所示:
将文件内容(使用 robocopy)从服务器复制到独特的本地系统上的路径名不是当前存在(例如,如果文件名为
foo
,则可以将其复制到foo.bak
。)使用 Windows Vista 中添加的原子重命名 Windows API 函数执行覆盖重命名(因此在 XP 及更早版本中不受支持,这些版本需要非原子的、可能有缺陷或损坏的非原子重命名;哎哟):移动文件传输()这样,您就可以瞬间将文件中包含的数据从原文件的内容“换出”到新文件的内容中。这意味着任何程序都不可能读取部分完整的文件——要么读取(完整的、未改变的)原始副本,或者它会读取完整、未更改的更新副本。它永远不会读取“不完整”的副本或两个文件的乱码组合。
此替代方法的缺点是:
- 我不知道有哪个程序可以实现这样的功能;
- 由于在复制时原始文件仍在那里,因此您需要两倍的存储空间。因此,如果您打算用另一个 1 GiB 文件覆盖 1 GiB 文件,则本地系统上总共需要 2 GiB 的存储空间,尽管是暂时的。
- 它仅适用于事务性 NTFS。这意味着,如果您的源文件系统或事务性覆盖的目标文件系统不是 NTFS,它将不起作用。您仍然可以将文件从网络共享复制到本地系统,但原子重命名无法在网络共享上运行,或者(除非他们将来添加)无法在 ReFS 上运行,后者可能有一天会成为我们的默认文件系统,就像多年前 NTFS 对 FAT32 所做的那样。