Linux 有何不同之处,允许我删除/替换 Windows 会抱怨文件当前正在使用的文件?

Met*_*ate 36 linux filesystems windows executable

我的例子是 Minecraft。在 Linux 上运行 Bukkit 时,我可以删除或更新 /plugins 文件夹中的 .jar 文件,只需运行“重新加载”命令即可。

在 Windows 中,我必须关闭整个服务器进程,因为当我尝试删除或替换它时,它会抱怨当前正在使用 .jar 文件。

这对我来说很棒,但为什么会发生?Linux 在这里做了什么不同的事情?

Ser*_*rge 45

Linux 删除文件的方式与 Windows 完全不同。首先,简要说明如何在 *unix 本机文件系统中管理文件。

该文件以称为i-node. 每个 i-node 在单个文件系统上都有一个唯一的编号。i-node 结构保存有关文件的不同信息,例如其大小、为文件分配的数据块等,但对于此答案,最重要的数据元素是link counter. 的directories是保持对文件记录的文件。每条记录都有它引用的索引节点号、文件名长度和文件名本身。这个方案允许一个人拥有“指针”,即“链接”到不同位置的同一个文件,但名称不同。i-node 的链接计数器实际上保留了引用该 i-node 的链接数。

当某个进程打开文件时会发生什么?首先该open()函数搜索文件记录。然后它检查这个索引节点的内存索引节点结构是否已经存在。如果某些应用程序已经打开了此文件,则可能会发生这种情况。否则,系统初始化一个新的内存索引节点结构。然后系统增加内存中的 i-node 结构打开计数器并将其文件描述符返回给应用程序。

删除文件的 Linux 库调用称为unlink. 此函数从目录中删除文件记录并递减索引节点的链接计数器。如果系统发现内存中的 i-node 结构存在并且其打开计数器不为零,则该调用将控制权返回给应用程序。否则,它检查链接计数器是否变为零,如果是,则系统释放为 i-node 和 i-node 本身分配的所有块并返回到应用程序。

应用程序关闭文件会发生什么?该函数close()递减打开计数器并检查其值。如果该值非零,则函数返回给应用程序。否则,它检查 i-node 链接计数器是否为零。如果为零,则在返回应用程序之前释放文件的所有块和索引节点。

此机制允许您在打开文件时“删除”文件。同时打开文件的应用程序仍然可以访问文件中的数据。因此,在您的示例中,JRE 仍然保持其文件版本处于打开状态,而磁盘上还有另一个更新版本。

此外,此功能允许您在不中断系统正常运行的情况下更新系统中的 glibc(libc) - 所有应用程序的核心库。

视窗

20 年前,除了 DOS 下的 FAT,我们还不知道任何其他文件系统。这个文件系统有不同的结构和管理原则。这些原则不允许您在打开文件时将其删除,因此 DOS 和最近的 Windows 必须拒绝对打开文件的任何删除请求。NTFS 可能会允许与 *nix 文件系统相同的行为,但 Microsoft 决定保持文件删除的习惯行为。

这就是答案。不短,但现在你有想法了。

编辑:关于Win32混乱来源的良好阅读:https : //blogs.msdn.microsoft.com/oldnewthing/20040607-00/?p = 38993 感谢@Jon

  • NTFS 实际上确实支持它,但是 C 库的 `fopen` 命令调用带有 `FILE_SHARE_DELETE` 标志的 `CreateFile`,因此它不允许大多数打开文件的程序使用它。 (10认同)
  • 强制性 Raymond Chen 链接:https://blogs.msdn.microsoft.com/oldnewthing/20040607-00/?p=38993 (2认同)