当一个程序打开一个文件,而另一个程序移动该文件以使其具有不同的路径名/文件名时,能第一个程序仍然对文件起作用,例如修改文件的内容或属性并将更改保存到文件?
我猜是。
当文件被移动时,它具有不同的路径名/文件名,但仍然具有相同的索引节点和数据块。
当程序打开文件时,文件的路径名/文件名用于查找其索引节点和数据块,并且程序直接或间接保存指向文件的索引节点和数据块的数据结构的指针。我不确定查找后路径名/文件名是否仍然有用。
如果答案是肯定的,那么哪些行为是预期的fromprograms,假设你要创建这样的程序?
- 他们是否会默默地处理移动的文件,
- 他们是否应通知用户移动并询问他们是否要继续处理移动的文件?
我经常在某些程序(emacs、某些 pdf 软件)中尽可能长时间地保持文件打开状态,时间足够长,以至于我可能会使用其他程序 ( mv
) 在同一时间的某个时刻移动/重命名它们。 Emacs 警告我文件已被移动,并且我不知道 Emacs 是否可以继续处理移动的文件,因此我通常必须关闭缓冲区并在新缓冲区中重新打开移动的文件,这在我看来很不方便。
谢谢。
答案1
打开的文件在 Linux 系统上的行为如何?提供了一些相关背景。
能第一个程序仍然对文件起作用,例如修改文件的内容或属性并将更改保存到文件?
只要第一个程序保持其文件描述符打开,它就可以使用使用该文件描述符的任何系统调用或库函数继续对文件进行更改。如果文件被移动到同一文件系统中的另一个目录,这些更改将应用于“新”文件;如果它被移动到另一个文件系统,则更改最终将丢失,除非另一个目录条目指向同一个 inode。
当文件被移动时,它具有不同的路径名/文件名,但仍然具有相同的索引节点和数据块。
如果它在同一文件系统内移动,是的。
当程序打开文件时,文件的路径名/文件名用于查找其索引节点和数据块,并且程序直接或间接保存指向文件的索引节点和数据块的数据结构的指针。我不确定查找后路径名/文件名是否仍然有用。
是的,在内核的帮助下:程序有一个文件描述符,它指向内核维护的文件描述。文件名就无关紧要了。
如果答案是肯定的,那么哪些行为是预期的fromprograms,假设你要创建这样的程序?
没有什么是预期的。某些程序打开文件并在对文件进行操作(包括向文件写入更新)期间保留返回的文件描述符。其他人打开一个文件,保留返回的文件描述符,但使用更复杂的写入重命名模式来写入文件;这包括 Emacs。 Emacs 此外还监视对其打开的文件的外部更改,并对任何此类更改发出警告。
最终,他们是你的文件,由您来跟踪您对它们所做的事情。有些程序会竭尽全力帮助您避免丢失数据,而另一些则不会。
答案2
第一个程序是否仍然可以处理该文件,例如修改文件的内容或属性并将更改保存到文件?
是的。
当文件被移动时,它具有不同的路径名/文件名,但仍然具有相同的索引节点和数据块。
是的。
当程序打开文件时,文件的路径名/文件名用于查找其索引节点和数据块,并且程序直接或间接保存指向文件的索引节点和数据块的数据结构的指针。
是的。如果删除文件,效果几乎相同,但在这种情况下很难保存任何修改。
我不确定查找后路径名/文件名是否仍然有用。
我不确定你是什么意思。我想这取决于人们认为有用的内容:如果您再次执行相同的路径查找,您可能会得到另一个文件,就像这里的情况一样。
Emacs 可能认为让用户知道文件在编辑时是否被修改是有用的。它必须做一些事情来检测这一点,要么轮询路径,要么使用inotify
等等。其他一些编辑则不介意。
我认为这里没有“必须”,不同的程序会做其作者认为有用的事情。
FWIW,我想到编辑器在处理备份文件的方式以及是否创建文件的新版本作为新索引节点,或者只是覆盖旧版本方面也有所不同。 Emacs 可能是这样配置的...
答案3
程序期望有哪些行为
它可能有助于理解程序不会收到任何其打开的文件已被重命名的自动通知。正如您所猜测的,该文件在移动后保持不变。它没有改变;这目录持有其名称已更改。这也是为什么目录权限,而不是文件的权限,控制是否可以删除(或创建)文件。
当目录被修改时,程序可以使用各种技术来收到通知。但大多数人不这样做,所以“预期”的行为将是沉默。
答案4
当程序打开文件时,文件的路径名/文件名用于查找其索引节点和数据块,
但程序只获取文件描述符,而不获取inode。 inode 用于文件系统内部。
vim 告诉我这一点 - 它甚至是一个红色错误:
E211: File "test" no longer available
即使我只是重命名它——通过移动。这个概念中没有重命名。文件包含很多东西,但它是实际用途的基本单位。这是一个错误,尽管我可以:w
再次这样做,就像我无论如何都会做的那样。
还有:
W11: Warning: File "test" has changed since editing started
仅涉及内容。
vi
似乎沉默了。