Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 删除文件后是否可以使用fread?_C - Fatal编程技术网

C 删除文件后是否可以使用fread?

C 删除文件后是否可以使用fread?,c,C,我用fopen打开了一个很大的文件流。 在对该流执行任何读取操作之前,我使用unlink()删除了该文件。 尽管如此,我还是能够阅读整个文件 我猜有一个与流关联的缓冲区,它保存文件的数据。但很明显,缓冲区是有限制的。这就是我选择大小为551126688字节或526MB的大文件的原因 我想知道这背后的确切原因是什么。 下面是我使用的测试代码 #include <stdio.h> #include <unistd.h> int main(){ FILE *fp;

我用fopen打开了一个很大的文件流。 在对该流执行任何读取操作之前,我使用unlink()删除了该文件。 尽管如此,我还是能够阅读整个文件

我猜有一个与流关联的缓冲区,它保存文件的数据。但很明显,缓冲区是有限制的。这就是我选择大小为551126688字节或526MB的大文件的原因

我想知道这背后的确切原因是什么。 下面是我使用的测试代码

#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;
}
#包括
#包括
int main(){
文件*fp;
长整型文件大小=0;
int bytes_read=0;
char-buf[1];
fp=fopen(“一个大文件”,“r”);
取消链接(“大文件”);
而(0!=(bytes_read=fread(buf,1,1,fp))){
文件大小+=读取的字节数;
}
printf(“文件大小为%llu\n”,文件大小);
返回0;
}
输出:
文件大小为551126688

在Unix和类似Unix的操作系统中,在关闭最后一个打开的文件句柄之前,文件实际上不会消失。对于临时文件,这是一个非常有用的技巧-如果在打开文件时立即取消链接,其他进程将看不到该文件,并且在程序关闭、结束或崩溃时将其从系统中删除。这有助于防止孤立临时文件的扩散

实际上(这里忽略了一些技术细节),Unix文件系统是以引用计数的。当您打开文件时,您实际上连接到文件的inode(这是文件实际内容所在位置的真实指示)。但是,取消文件链接只会删除目录条目,因此文件不再有名称。如果文件空间(即索引节点)不在任何目录条目中,并且没有人打开它,则文件系统将仅回收该文件空间。其他进程无法以普通方式打开它,因为它们无法将文件名映射到inode


请注意,Unix文件系统允许多个目录项指向同一索引节点——我们称之为“硬链接”。如果执行“ls-l”,其中一个字段是指向同一inode的硬链接数,如果执行“ls-li”,则可以看到实际inode地址。

从手册页中取消链接:

unlink()从列表中删除一个名称 文件系统。如果那是最后一个名字 链接到文件,并且没有进程 打开该文件的文件将被删除并删除 它所使用的空间是由 可重复使用

如果名称是指向的最后一个链接 文件,但任何进程仍具有 文件打开该文件将保留在中 存在到最后一个文件 引用它的描述符是 已关闭。

粗体部分解释了该行为。:-)


[编辑]顺便说一句,您应该在返回语句之前使用fclose()关闭文件。。。[/edit]

Linux
中,文件只有在最后一个打开的句柄关闭时才真正被删除

人们通常以这种方式使用临时文件:
mkstemp(3)
,然后立即
取消链接(2)
。这样,只有您可以访问文件的数据,其他进程无法访问


即使另一个进程创建了其他同名文件,新文件也不会与原始文件有任何共同之处。

在某些系统上,如linux,只要进程仍然打开文件系统,您仍然可以轻松访问文件系统上没有名称的文件。中有一个文件描述符列表

/proc/<pid>/fd

天哪。。。我的眼睛不好了。我以为上面说的是“弗雷德可能吗…”弗雷德是麦金塔Common Lisp的编辑,而Digitool从未成功地迁移到OSX。遗憾的是,我不知道在现代的Macintosh上这仍然是可能的,尽管许多MCL仍然存在。好吧,这是一个快速的答案:),但我想知道系统内部到底发生了什么。我想知道为什么其他进程看不到该文件。我是说内部发生了什么,你能解释一下吗:)因为不再有指向inode的文件名了。所以,如果你已经有了一个文件句柄,你仍然可以使用它(在任何进程中),但是你不能再得到一个新的了。这是否意味着此inode指向的位置包含不一致的数据,因为它可能由任何新文件(在取消链接后创建)写入?此外,根据此逻辑,文件大小将正确显示,但读取的数据可能/可能不正确,这取决于任何新文件的inode是否指向这些位置。@Aman,如上所述,在没有打开的文件句柄和目录条目之前,操作系统不会回收inode。除非在您解除链接之前将其打开,否则任何内容都无法写入该文件空间。如果在返回之前不执行fclose(fp)操作,会发生什么情况。当进程结束时,fp没有意义,因为进程的地址空间被释放。如果我错了,请纠正我。1)如果您正在写入而不是读取,缓冲输出的最后一位可能会丢失2)如果您是线程而不是进程,文件句柄将保持打开状态3)这是一种糟糕的样式,因为它会使读卡器停止并仔细考虑(1)还是(2)应用,操作系统根本不关心你愚蠢的缓冲文件IO——重要的是你有一个打开的文件描述符,然后你死了,这样它就可以关闭fd(并取消文件链接)。我同意puetzk的观点,而且当进程结束并将资源返回到操作系统时,打开的文件句柄会发生什么情况还没有定义。这取决于操作系统要做什么。续。。。好的实践是表明您可以控制代码中的资源。如果没有其他内容,则fclose()会显示不想再使用打开的文件的位置。此外,它还避免了原始问题中所示的不必要行为:-数据访问此数据需要哪些权限?我想你需要
# 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