首先,不要将标准库<stdio.h>调用(如fprintf(3)or fopen(3))与系统调用(如open(2)orclose(2)或sync(2))混为一谈,因为前者是库例程,它们使用进程内缓冲区来存储系统不知道的临时数据,而其他是操作系统接口,使系统从现在开始负责数据维护。您将很容易区分它们,因为前者使用FILE *描述符进行操作,而最后使用int整数描述符进行操作。
因此,如果您使用系统调用来确保您的数据正确同步到磁盘,则绝对有必要fflush(3)sync(2)在执行文件系统或fsync(2)调用 之前首先处理进程的缓冲区数据。
不sync(2)保证在时间fclose(3)或什至close(2)准时发生,或者在atexit()您的进程之前执行的回调中发生exit()。
出于性能原因,操作系统缓冲区被延迟写入,并且close(2)不是使其触发此类事件的事件。试想一下,许多进程可以同时读取和写入同一个文件,并且每个close(2)触发文件系统刷新都可能很难实现。操作系统会定期、umount(2)系统调用、系统关闭以及对系统调用的特定调用sync(2)触发此类fsync(2)调用。
如果您需要保持FILE *fd描述符打开,只需fflush(fd)对该描述符执行 a 以确保操作系统首先拥有所有用于fwrite(3)d 或fprintf(3)ed 数据的缓冲区。
所以最后,如果您使用<stdio.h>函数,首先对您写入fflush()的所有描述符执行 a ,或者调用以告诉 stdio 在一次调用中同步所有描述符。然后执行or调用以确保您的所有数据物理上都在磁盘上。无需关闭任何东西。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(或打开的文件结构)上没有任何内容可让您获取用于打开该文件的路径。使用临时文件的一种常见方法是创建它们并立即创建它们unlink(2),因此没有人可以再次打开它。只要您保持文件打开,您就可以访问它,但不再有指向它的路径。