为什么进程退出时数据没有刷新到文件?
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);
}
结果:没有数据写入 a.txt
我预计这很好。因为系统将关闭文件句柄,然后文件系统驱动程序在其 Close 处理程序中刷新未刷新的数据。但事实并非如此。 我在 EXT4、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 再次测试了它。而且冲洗得很好。
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;
}
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
I expected this is fine. Because the system will close the file handle and then the filesystem driver flushes the unflushed data in his Close handler. But it wasn't.
I tested this code on EXT4, ubuntu 11.10
Question:
I thought ALL filesystems must flush unflushed data at his close processing.
Posix doesn't have the rule?
P.S This code worked well (flushed well) on 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;
}
Edit:
I tested it again with system call write
. And it was flushed well.
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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
更多
发布评论
评论(2)
这与文件系统无关,而是您正在使用的 C 实现的行为决定了何时刷新打开的流。
在 POSIX 下,
SIGTERM
信号的默认操作为:根据 C 标准以及是否刷新的选择,
_exit()
相当于_Exit()
标准未指定流:假设您在 Linux 上使用 glibc,来自 文档(强调我的):
我不熟悉 Windows 的
WriteFile
和TerminateProcess
,因此我无法评论记录的行为是什么。This isn't anything to do with the filesystem, rather it's the behaviour of the C implementation you are using that determines when open streams are flushed or not.
Under POSIX, the default action action for the
SIGTERM
signal is:_exit()
is equivalent to_Exit()
according to the C standard and the choice of whether to flush streams is not specified by the standard:Assuming you are using glibc on Linux, from the documentation (emphasis mine):
I'm not familiar with the Windows'
WriteFile
andTerminateProcess
so I can't comment on what the documented behaviour is.它与文件系统驱动程序没有任何关系。问题在于 CRT 正在缓冲文件流本身。您可以使用 setvbuf() 设置缓冲区大小,如果您不使用此函数,它将使用默认值。当您使用 WriteFile() 时,应用程序中没有缓冲,输出缓冲在操作系统的文件系统缓存中。免受应用程序突然中止的影响。
您必须调用 fflush() 才能实现相同的目的。
It doesn't have anything to do with file system drivers. The issue is that the CRT is buffering the file stream itself. You set the buffer size with setvbuf(), it uses a default if you don't use this function. There's no buffering in the application when you use WriteFile(), output is buffered in the operating system's file system cache. Immune from abrupt app aborts.
You'll have to call fflush() to achieve the same.