每当我在共享的网络托管环境中替换静态 HTML 文件时,我都会担心这个问题。
当将一个文件粘贴(或通过 FTP 传输)到另一个同名文件“上方”时,是否会有一段短暂的时间,在此期间两个文件都不存在?
如果我index.html
在网络服务器上有一个文件,并在其上粘贴一个新文件index.html
,请求该文件的用户是否有可能收到错误404
?
答案1
这实际上取决于两个因素:文件如何被替换以及 WWW 服务器底层的操作系统是什么。以下三个示例说明了这有何不同:
- 符合 POSIX 标准的操作系统,使用
mv
从预先准备的临时文件更新文件:mv
保证调用(或表现得像)rename()
按照 POSIX 规范,这又保证了目标文件名(在本例中为index.html
)始终会引用一些文件,无论是原始文件还是新文件。并且文件内容永远不会处于部分写入状态。这同样适用于 FTP/HTTP 服务器,它会上传到临时文件,然后
rename()
在临时文件完全上传后调用 将临时文件移动到其指定的目的地。 - Microsoft Windows 使用
MOVE
某种命令要更新预先准备的临时文件:命令的通常实现MOVE
(如这里所示)MOVE
ReactOS命令的来源) 就是调用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
不存在但临时文件名或文件前一版本的备份存在的短暂时间间隔。(前者可能位于临时目录中,因此从外部不可见。)