为什么重命名加载的.net程序集工作?

我已经创建了ac#.net(4.5)命令行应用程序。 这个应用程序什么都不做,但保持开放:

class Program { static void Main(string[] args) { Console.WriteLine("started"); Console.ReadLine(); } } 

如果我在资源管理器中导航到此文件,我可以在程序运行时使用F2重命名它。

如果我尝试删除它,会显示一条消息: 在此处输入图像描述

我可以理解,无法删除已加载的程序集。 将加载的程序集从一个文件夹移动到另一个文件夹也不起作用。

但为什么可以重命名呢?

这是有意的吗? 是否有用例重命名现有/已加载的程序集?

文件由文件系统中的两个主要结构表示。 首先是目录条目 ,它存储有关文件的元数据。 像文件名,大小,属性和时间戳一样。 接下来是存储文件数据的集群链。

加载程序集会导致为程序集创建内存映射文件。 优化,它确保您只需支付实际使用的部件。 在实际需要之前,文件数据不会被读入RAM。 需求分页虚拟内存操作系统(如Windows)的核心function。

内存映射文件会锁定文件,以确保其他进程无法更改文件数据 。 这将是灾难性的,RAM中的数据将不再与文件中的数据匹配。 Windows中的锁仅保护文件数据 ,而不保护文件的元数据 。 或者换句话说,您仍然可以修改文件的目录条目,只要它不会修改文件数据。

因此重命名文件不是问题,只修改目录条目。 即使将文件从一个目录移动到另一个目录也不是问题,只需更改目录条目的位置,只要文件大到足以要求群集,它就不会修改文件数据。 将文件从一个驱动器移动到另一个驱动器是一个问题,因为这需要一个也删除原始文件数据的副本。 无法删除文件,这也会删除文件数据。

就磁盘上写的内容而言,重命名并没有太大变化,实际上它可能只会更改文件分配表和某些文件元数据。

因此,尽管名称发生了变化,包含程序的磁盘块仍然可以复制到内存中或执行。

到目前为止,Imo最好的答案来自https://superuser.com/questions/488127/why-can-i-rename-a-running-executable-but-not-delete-it

确实没有重命名文件的事情。 一个文件可以有多个名称或没有名称,因此它不是您要重命名的文件而是目录条目。 重命名是对目录条目的操作,不受文件被锁定以执行的影响。