Возможен ли фред после удаления файла? - PullRequest
2 голосов
/ 03 февраля 2009

Я открыл поток файлов в очень большой файл, используя fopen. Перед выполнением любой операции чтения в этом потоке я удалил файл, используя unlink (). И все же я смог прочитать весь файл.

Я предполагаю, что с потоком связан буфер, в котором хранятся данные файла. Но очевидно, что у буфера будет предел. По этой причине я выбрал файл a_big_file, размер которого был 551126688 байт или 526 МБ.

Я хочу знать, какова точная причина этого. Вот тестовый код, который я использовал.

#include <stdio.h>
#include <unistd.h>

int main(){

    FILE *fp;
    long long int file_size = 0;
    int bytes_read = 0;
    char buf[1];

    fp = fopen("a_big_file", "r");

    unlink("a_big_file");

    while(0 != (bytes_read = fread(buf, 1, 1, fp))){
        file_size += bytes_read;
    }

    printf("file_size is %llu\n", file_size);

    return 0;
}

Выход: размер_файла 551126688

Ответы [ 4 ]

17 голосов
/ 03 февраля 2009

В Unix и Unix-подобных операционных системах файл фактически не исчезает, пока не будет закрыт последний дескриптор открытого файла на нем. Это очень полезный прием для временных файлов - если вы отсоедините его, как только откроете, файл не будет виден другим процессам и будет удален из системы, как только ваша программа закроет его, завершит или сбои. Это помогает предотвратить распространение временных файлов.

Практически (здесь мы опускаем некоторые технические детали) происходит то, что файловые системы Unix подсчитываются. Когда вы открываете файл, вы на самом деле подключаетесь к иноду файла (который является реальным указанием того, где находится фактическое содержимое файла). Но удаление ссылки на файл просто удаляет запись в каталоге, поэтому у файла больше нет имени. Файловая система будет восстанавливать файловое пространство (т. Е. Индекс) только в том случае, если его нет ни в одной записи каталога, и ни у кого его нет. Другие процессы не могут открыть его обычным способом, потому что они не могут сопоставить имя файла с индексом.

Обратите внимание, что файловые системы Unix позволяют нескольким записям каталога указывать на один и тот же индекс - мы называем это "жесткой ссылкой". Если вы выполните «ls -l», одним из полей будет количество жестких ссылок на тот же самый инод, а если вы выполните «ls -li», вы увидите фактический адрес инода.

9 голосов
/ 03 февраля 2009

Со страницы руководства для отмены ссылки:

unlink () удаляет имя из файловая система. Если это имя было последним ссылка на файл и нет процессов файл открыть файл удаляется и пространство, которое он использовал, сделано доступны для повторного использования.

Если имя было последней ссылкой на файл, но все процессы имеют открыть файл файл останется в существование до последнего файла дескриптор ссылаясь на это закрыт.

Жирный бит объясняет поведение. : -)

[edit] Кстати, вы должны действительно закрыть файл с помощью fclose () перед оператором return ... [/ edit]

3 голосов
/ 03 февраля 2009

В некоторых системах, таких как linux, вы можете легко получить доступ к файлам, которые не имеют имени в файловой системе, если процесс все еще имеет их открытым. Есть список файловых дескрипторов в

/proc/<pid>/fd

Редактировать : Согласно комментарию Пола Томблина , вы можете получить доступ к этому каталогу, только если вы являетесь тем же пользователем, что и процесс или пользователь root.

Например:

# Create a file with cat
chris@shrubbery:~$ cat > MYFILE
Hello

# Suspend the process and find its pid
[1]+  Stopped                 cat > MYFILE
chris@shrubbery:~$ ps waux | grep cat
chris     1311  0.0  0.0   5088   668 pts/6    T    14:29   0:00 cat
chris     1313  0.0  0.0   5168   840 pts/6    R+   14:29   0:00 grep cat

# Inspect the list of open files
chris@shrubbery:~$ cd /proc/1311/fd
chris@shrubbery:/proc/1311/fd$ ls -l
total 0
lrwx------ 1 chris chris 64 2009-02-03 14:29 0 -> /dev/pts/6
l-wx------ 1 chris chris 64 2009-02-03 14:29 1 -> /home/chris/MYFILE
lrwx------ 1 chris chris 64 2009-02-03 14:29 2 -> /dev/pts/6

# View MYFILE from the symlink on the /proc pseudofilesystem.
chris@shrubbery:/proc/1311/fd$ cat 1
Hello

# Delete the filename /home/chris/MYFILE
chris@shrubbery:/proc/1311/fd$ rm /home/chris/MYFILE
chris@shrubbery:/proc/1311/fd$ cat /home/chris/MYFILE
cat: /home/chris/MYFILE: No such file or directory

# But the process still has it open. 
# The /proc system knows the original name was deleted
chris@shrubbery:/proc/1311/fd$ ls -l
total 0
lrwx------ 1 chris chris 64 2009-02-03 14:29 0 -> /dev/pts/6
l-wx------ 1 chris chris 64 2009-02-03 14:29 1 -> /home/chris/MYFILE (deleted)
lrwx------ 1 chris chris 64 2009-02-03 14:29 2 -> /dev/pts/6

# We can still view the file, useful for debugging.
chris@shrubbery:/proc/1311/fd$ cat 1
Hello
0 голосов
/ 03 февраля 2009

В Linux файл действительно удаляется только после закрытия последнего открытого дескриптора.

Люди обычно используют временные файлы следующим образом: mkstemp(3) с последующим немедленным unlink(2). Таким образом, только вы можете получить доступ к данным файла, никакой другой процесс не сможет.

Даже если другой процесс создаст другой файл с тем же именем, новый файл не будет иметь ничего общего с исходным файлом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...