将一个文件粘贴到另一个同名文件“上方”时,是否会有一段短暂的时间,在此期间两个文件都不存在?

将一个文件粘贴到另一个同名文件“上方”时,是否会有一段短暂的时间,在此期间两个文件都不存在?

每当我在共享的网络托管环境中替换静态 HTML 文件时,我都会担心这个问题。

当将一个文件粘贴(或通过 FTP 传输)到另一个同名文件“上方”时,是否会有一段短暂的时间,在此期间两个文件都不存在?

如果我index.html在网络服务器上有一个文件,并在其上粘贴一个新文件index.html,请求该文件的用户是否有可能收到错误404

答案1

这实际上取决于两个因素:文件如何被替换以及 WWW 服务器底层的操作系统是什么。以下三个示例说明了这有何不同:

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

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

  • Microsoft Windows 使用MOVE某种命令要更新预先准备的临时文件:命令的通常实现MOVE(如这里所示)MOVEReactOS命令的来源) 就是调用MoveFileEx()标记MOVEFILE_REPLACE_EXISTING设置为打开。这至少在 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 服务器的文件存储区域,则取决于您使用的工具。

答案2

该文件仍会存在,但如果他们在错误的时间请求它,它可能处于中间状态(空或截断)。

如果处理文件上传的程序足够智能,它可能会上传一个新名称,然后替换旧文件。如果是这样,确实会有一个非常名称index.html不存在但临时文件名或文件前一版本的备份存在的短暂时间间隔。(前者可能位于临时目录中,因此从外部不可见。)

相关内容