将一个文件“粘贴”到另一个同名文件上时,是否有一个文件不存在的短暂时刻?

Clo*_*boy 5 filesystems

每当我在共享 Web 托管环境中替换静态 HTML 文件时,这曾经让我担心。

当将一个文件粘贴(或 FTPing)到另一个同名文件上时,是否有一个短暂的时刻两个文件都不存在?

如果我index.html在 Web 服务器上有一个新的粘贴index.html在它上面,请求该文件的用户是否有可能会收到404错误?

Jde*_*eBP 3

它实际上取决于两件事:文件如何被替换以及 WWW 服务器底层的操作系统是什么。以下三个示例展示了这如何产生影响:

  • 符合 POSIX 的操作系统用于mv从预先准备的临时文件更新文件: mv保证调用(或行为类似)rename(),而根据 POSIX 规范,这又保证始终使用目标文件名,在本例中index.html,将始终引用某个文件,无论是原始文件还是新文件。并且文件内容永远不会处于部分写入的状态。

    这同样适用于上传到临时文件的 FTP/HTTP 服务器,然后rename()在临时文件完全上传时调用 来将临时文件移动到指定的目的地。

  • Microsoft Windows 使用某种MOVE命令来更新预先准备好的临时文件:命令的通常实现MOVE(可以在ReactOS命令的源代码MOVE中看到)是在标记设置MoveFileEx()MOVEFILE_REPLACE_EXISTINGon 的情况下进行调用。至少在 Windows NT 上(因为该标志被传递到支持原子重命名所需的文件系统驱动程序),这可以保证指定的文件index.html始终存在,就像 POSIX 和rename().

    这同样适用于上传到临时文件的 FTP/HTTP 服务器,然后MoveFileEx()在临时文件完全上传时调用 来将临时文件移动到指定的目的地。

  • Microsoft Windows 使用某种命令COPY预先准备的临时文件更新文件:COPY命令不使用MoveFileEx(). 相反,它打开现有文件,将其截断为零长度,然后就地重写(再次参见CopyFileEx()ReactOS)。虽然名称永远不会指向index.html文件,但它所指向的文件在复制过程中将处于部分写入状态,并且 WWW 服务器可能会提供截断的版本该文件的结果。

    这同样适用于 FTP/HTTP 服务器,它要么 (a) 仅就地上传文件,截断并覆盖原始文件,要么 (b) 上传到临时文件,然后将临时文件复制到其指定的目的地。

简而言之:如果您通过 FTP/HTTP 服务器上传,则取决于 FTP/HTTP 服务器内部的工作方式。如果您直接修改WWW服务器的文件存储区域,那么这取决于您使用什么工具来执行此操作。