
我理解,有时在复制文件时,系统会“缓存”复制过程,或“延迟”复制过程:即,复制过程实际完成所需的时间比“过程完成”UI 通知让您相信的时间要长一些。这就是为什么在复制到外部硬盘驱动器后立即直接移除外部硬盘驱动器并不好,而是需要稍等片刻再移除。
那么,现在假设我将一个文件复制到同一驱动器内的另一个文件夹,或者复制到完全不同的驱动器。现在,我立即将该源文件移动到另一个文件夹,或者将其删除(将其移至垃圾箱);就文件损坏而言,这样做会危及源文件或其新生成的副本吗?或者更确切地说,计算机是否有一个系统来防范这种情况,在复制完全完成之前自动阻止对源文件的任何实际移动或删除?
答案1
因此,现在假设我将文件复制到同一驱动器内的另一个文件夹,或者复制到完全不同的驱动器。
这是一个非常重要的区别,因为不同的驱动器意味着不同的文件系统,很可能具有不同的存储语义、缓存行为等。所以让我们让事情变得简单并留在同一个文件系统内。
或者更确切地说,计算机是否有一个系统来防范这种情况,在复制完全完成之前自动阻止任何实际移动或删除源文件?
由于您的重点是 Windows,所以答案是肯定的。Windows 实施了一种方法,即对文件执行某些操作的应用程序默认会锁定这些文件,以便其他应用程序无法访问它。第一个对文件执行某些操作的应用程序需要决定允许其他应用程序执行哪些操作,读取、写入、删除等。如果没有明确的决定,其他应用程序将无法执行任何操作,包括在复制过程中移动文件。请记住,复制过程是一个应用程序尝试同时移动文件到另一个应用程序等。有关详细信息,请查看创建文件以及它的论点dwShareMode
。
因此,虽然存在某种安全网,但很可能不需要:文件系统缓存无论如何都是由操作系统和文件系统透明处理的(大多数情况下)。总体目标是用户和应用程序不需要处理细节,包括复制和知道何时真正复制数据以进行进一步操作。应用程序可能对这些细节感兴趣,例如可能会使用刷新命令,这些命令告诉操作系统或文件系统它们现在将缓存写入某个文件的数据,而调用应用程序则等待完成。但在大多数情况下,这不是必要的。
这包括复制后的移动:如果仅涉及文件系统缓存,而不是例如文件仍然被复制过程本身锁定,例如 Windows 资源管理器,您可以自由移动文件,即使尚未将所有数据写入磁盘。这是因为大多数文件系统不直接将实际文件数据与其文件名或路径关联,而是独立处理两者。因此,数据存储在某个地方,在另一个地方存储文件名,引用其父路径并引用数据。因此,当文件名本身被更改或移动到其他目录时,它只需保留对实际数据的引用,操作系统和文件系统可以同时继续将其缓存刷新到它们已经与文件名关联的位置。
https://en.wikipedia.org/wiki/Inode
现代文件系统甚至不需要关心或事先知道需要写入多少数据,它们只是按照某些规则在某处分配数据块,并将每个分配的块与已经存在的完整名称对象相关联。
答案2
就文件损坏而言,这样做是否会危及源文件或其新制作的副本?或者说,计算机是否有一个系统来防范这种情况,在复制完成之前自动阻止任何实际的移动或删除源文件?
以上都不是。此时文件复制过程不依赖于原始文件;它有已经读取了所有原始文件并将所有数据“写入”新文件,因此“过程完成”UI 通知会告诉您真相。
实际被缓存的只有那些写入操作– 有一个完全分离缓存层与复制无关,而是与写入磁盘有关。任何文件写入,无论是从一个文件复制到另一个文件还是只是保存文档,都首先由操作系统缓冲在内存中,然后才刷新到物理存储中。(也就是说,就程序而言,数据已经“在”文件中,只是不在文件中在磁盘上然而。)
答案3
在同一文件系统(分区)内移动或不同文件系统之间移动会有细微的差别。
用于在同一文件系统内移动:磁盘上的文件数据与文件表内的元数据完全分开。元数据包含指向数据的指针,但与数据无关,也就是说,文件条目可以移动到另一个文件夹,而无需移动数据。
在您的案例中,可能发生的情况是文件的数据尚未终止移动并且仍在缓存中,而文件条目已移动到同一文件系统中的其他位置。不会遇到任何问题,并且文件的数据将继续从缓存中刷新,而文件已位于其新文件夹中(包括当此文件夹为回收站时)。
用于在不同的文件系统内移动:Windows 将尝试将文件的数据复制到新磁盘,然后在新的文件表中创建并登录,最后删除源磁盘上的文件。
在复制数据时,每个源块都会被读取和复制。如果源数据尚未写入源磁盘中的位置,则可能会从内存缓存中读取源数据,然后将其复制到新磁盘。例如,很有可能在缓存中发现相同的数据重复两次,而每个副本都注定要写入不同的磁盘。
对于 Windows,当复制操作完成后,即使并非所有块都写入两个磁盘,源文件也将被删除。这将使内存缓存中的所有块无效,因此未写入源文件的块将被取消。在这种情况下,可能出现这种情况:在执行操作后立即删除或移动文件最终会比等待写入终止后再执行操作更高效。
复制后立即删除:如上所述,这将取消内存缓存中仍存在的所有未写入的块,因此此类块永远不会被写入磁盘。