int main(int argc, char *argv[]) { FILE *fp = fopen("a.txt", "wt"); fprintf(fp, "AAAA"); // No flush. and No close raise(SIGTERM); exit(EXIT_SUCCESS); }
result: No data has written to a.txt
我预料这很好。 因为系统将closures文件句柄,然后文件系统驱动程序在其Close处理程序中刷新未刷新的数据。 但事实并非如此。 我在EXT4上testing了这个代码,ubuntu 11.10
问题:我认为所有文件系统都必须在他的密切处理中刷新未刷新的数据。
Posix没有规则?
PS这个代码在NTFS,Win7上运行的很好(刷新的很好)
int _tmain(int argc, _TCHAR* argv[]) { HANDLE h = CreateFile(L"D:\\a.txt", GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_ALWAYS, 0, 0); BYTE a[3]; memset(a, 'A', 3); DWORD dw; WriteFile(h, (PVOID)a, 3, &dw, 0); TerminateProcess(GetCurrentProcess(), 1); return 0; }
编辑:
我用系统调用write
再次testing它。 它被冲洗得很好。
int main(int argc, char** argv) { int fd = open("a.txt", O_CREAT|O_TRUNC|O_WRONLY); char buf[3]; memset(buf, 'A', 3); size_t result = write(fd, buf, 3); raise(SIGTERM); exit(EXIT_SUCCESS); return 0; }
它与文件系统驱动程序没有任何关系。 问题是CRT正在缓冲文件流本身。 你用setvbuf()设置缓冲区大小,如果你不使用这个函数,它使用默认值。 当使用WriteFile()时,应用程序中没有缓冲区,输出缓冲在操作系统的文件系统缓存中。 免于突然的应用程序中止。
你将不得不调用fflush()来达到同样的效果。
这与文件系统无关,而是您正在使用的C实现的行为决定何时打开流。
在POSIX下, SIGTERM
信号的默认动作是:
过程异常终止。 这个过程终止了_exit()的所有后果…
_exit()
等同于根据C标准的_Exit()
,并且标准没有指定是否刷新流的选择:
_Exit()和_exit()函数不应该调用使用atexit()注册的函数,也不要调用任何注册的信号处理程序。 无论是打开或关闭流,或临时文件被删除是实施定义…
假设你在Linux上使用glibc,从文档 (重点是我的):
当一个进程由于某种原因而终止时(或者是程序终止,或者是一个信号的结果),就会发生下面的事情:
- 该进程中所有打开的文件描述符都被关闭。 请参阅低级I / O。 请注意,流程终止时不会自动刷新流 ; 请参阅Streams上的I / O。
我不熟悉Windows的WriteFile
和TerminateProcess
所以我不能评论记录的行为是什么。