首先,不要混用标准库<stdio.h>
调用(如fprintf(3)
或fopen(3)
)与系统调用(如open(2)
或close(2)
或sync(2)
)作为剂是使用过程中的缓冲区存储临时数据库例程,系统不知道,其他系统是操作系统接口,使系统从现在开始负责数据维护。您将轻松区分它们,因为前者使用FILE *
描述符进行操作,而最后使用整数描述符来操作int
。
所以如果你使用一个系统调用,以确保您的数据正确同步到磁盘,它你做的文件系统sync(2)
或fsync(2)
调用之前是绝对neccessary先fflush(3)
你的进程缓冲区中的数据。
没有sync(2)
是必要的fclose(3)
甚至上close(2)
时间发生,或在atexit()
回调exit()
之前,你的过程一样。
由于性能原因,操作系统缓冲区被写入延迟,而close(2)
不是触发此类事件的事件。只要认为许多进程可以同时读取和写入同一个文件,并且每个触发文件系统刷新都可能很难实现。操作系统会定期触发此类调用,系统调用会在umount(2)
之间,系统关闭以及对系统调用的sync(2)
和fsync(2)
进行特定的调用。
如果你需要保持FILE *fd
描述符开,只是做一个fflush(fd)
为描述符,以确保操作系统具有fwrite(3)
d或fprintf(3)
版数据首次所有缓冲区。
所以最后,如果你正在使用<stdio.h>
功能,首先做一个fflush()
为你写的所有FILE *
描述符,或致电fflush(NULL);
告诉标准输入输出,以同步所有描述在一个电话。然后执行sync(2)
或fsync(2)
调用以确保您的所有数据在物理上位于磁盘上。无需关闭任何东西。
FILE *fd;
...
fflush(fd);
fsync(fileno(fd));
/* here you know that up to the last write(2) or fwrite(3)...
* data is synced to disk */
顺便说一句,你要去/dev/fd/<number>
获得描述符(你以前有)的做法是错误的,原因有二:
一旦你关闭你的描述,/dev/fd/<number>
已不再你想要的描述符。通常情况下,它不存在,甚至。试试这个吧:
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
int main()
{
int fd;
char fn[] = "/dev/fd/1";
close(1); /* close standard output */
fd = open(fn, O_RDONLY); /* try to reopen from /dev/fd */
if (fd < 0) {
fprintf(stderr,
"%s: %s(errno=%d)\n",
fn,
strerror(errno),
errno);
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
} /* main */
你只有文件描述符才能得到打开文件所属的目录。在一个多链接文件中,可能有成千上万个目录指向它。 inode(或者在打开的文件结构中)没有任何东西可以让你获得用于打开该文件的路径。使用临时文件的一种常见方式就是创建它们,并立即使用它们,因此没有人可以再次打开它。尽管您保留文件打开,您可以访问它,但没有路径指向它了。
谢谢,但这不是一个选项。它会使每个write()块相对较长的时间,我们承担不起。文件关闭时是同步的好时机。 – Arnout