2015-12-22 3 views
2

Я изучаю количество ссылок на файл. Только когда количество ссылок достигает 0, содержимое файла будет удалено. В моем тесте процесс открывает файл в каталоге «/ home/hel/myfile» и sleep 10 (s). В то же время я удаляю его с помощью «rm/home/hel/myfile». Затем я использую команду «ls» и не вижу такой файл. Но на самом деле файл все еще существует, потому что fd не был закрыт. Если это так, «ls» не может показать, действительно ли файл существует. Я смущен насчет «лс». Или как я могу судить, что файл действительно существует?ссылка count и команда 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». Ссылка не совпадает с файловым дескриптором; это отдельная ссылка на занятые inodes ... – tink

ответ

2

Имя файла как ярлык, указывающий на реальные данные. Реальные данные хранятся в an 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, теперь индексный дескриптор имеет две ссылки.

$ 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. Пока есть открытый дескриптор, он не позволит перезаписывать индексный дескриптор.

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