我正在学习文件链接计数。仅当链接计数达到0时才能删除文件的内容。在我的测试中,该过程在目录" / home / hel / myfile"中打开一个文件。和睡10(s)。同时我使用" rm / home / hel / myfile"删除它。然后我使用命令" ls"并显示没有这样的文件。但事实上,该文件仍然存在,因为fd尚未关闭。如果是这样," ls"无法显示文件是否真的存在。我对#34; ls"感到困惑。或者我如何判断文件真的存在?
#include <fcntl.h>
#include <stdlib.h>
int main(void)
{
int fd;
fd = open("/home/hel/myfile", O_RDWR);
if (fd < 0) {
exit(-1);
}
sleep(10); // sleep 10(s)
close(fd);
return 0;
}
答案 0 :(得分:2)
文件名就像指向真实数据的标签。实际数据存储在an inode中。 inode通常只有一个文件名指向它,链接数为1。但它可以有不止一个。
这是一个直观的例子。创建普通文件时,它会将数据放入新的inode中,并将文件名指向该文件。
$ echo "foo" > some/file
"some/file" -> [data: "foo", links: 1]
当你制作另一个文件时,会发生同样的事情。
$ echo "bar" > another/file
"some/file" -> [data: "foo", links: 1]
"another/file" -> [data: "bar", links: 1]
但是如果你创建一个hard link,现在inode有两个链接。
$ ln some/file some/link
"some/file" -> [data: "foo", links: 2]
^
"some/link" -----/
"another/file" -> [data: "bar", links: 1]
实际上,普通文件是硬链接。除了文件名之外,没有什么可以区分some/file
和some/link
。两者都不是“真正的”文件,它们都是链接。
如果删除链接,则链接计数递减。这就是为什么在某些语言中,您调用unlink
来删除文件。
$ rm some/file
"some/link" -> [data: "foo", links: 1]
"another/file" -> [data: "bar", links: 1]
当它达到0时,可以覆盖inode。数据仍然存在,但没有任何指向它。这就是您有时可以恢复已删除文件的原因。
$ rm some/link
[data: "foo", links: 0]
"another/file" -> [data: "bar", links: 1]
文件句柄怎么样?它们不会更改链接计数。相反,在Unix(不是Windows)上,操作系统会跟踪给定inode的打开句柄数量。只要有一个打开的句柄,它就不允许覆盖inode。
fd = open("another/file", O_RDWR);
[data: "foo", links: 0]
fd ---\
\/
"another/file" -> [data: "bar", links: 1]
$ rm another/file
[data: "foo", links: 0]
fd -> [data: "bar", links: 0]
close(fd);
[data: "foo", links: 0]
[data: "bar", links: 0]
这使您可以执行诸如创建临时文件,打开读取和写入的句柄以及立即删除它之类的操作。然后程序可以继续读写临时磁盘存储,但没有人能看到该文件。