2015-12-22 139 views
2

我正在学习文件链接计数。只有链接计数达到0时,才能删除文件的内容。在我的测试中,该进程在目录“/ home/hel/myfile”中打开一个文件并睡眠10(s)。同时我使用“rm/home/hel/myfile”删除它。然后我使用命令“ls”并显示No这样的文件。但事实上,该文件仍然存在,因为fd尚未关闭。如果是这样,“ls”不能显示文件是否真的存在。我对“ls”感到困惑。或者我怎么能判断一个文件真的存在?链接计数和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

你对链接是什么感到困惑,而不是关于“ls”。链接与文件句柄不同;这是一个单独的参考信息被占领的inode ... – tink

回答

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/filesome/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] 

这可以让你做一些事情,如创建一个临时文件,打开一个句柄来读写它,并立即删除它。然后该程序可以继续读取和写入临时磁盘存储,但没有人可以看到该文件。

+1

非常清楚,真的很有用。谢谢! – hel