(WINAPI创建文件 - WINAPI写文件) 当我使用winapi函数写入文件时,在winapi(FILE_FLAG_NO_BUFFERING)中使用的标志工作正常。
(WINAPI创建文件 - CFile - 写入文件) 在这种情况下,错误也已发生,但这是因为CFile对象中缺少文件名,这是从winapi CreateFile函数接收的文件句柄创建的。
(CFile创建文件 - Cfile - 写文件) 当我使用这个标志(CFile :: osNoBuffer)时,当我尝试向文件写入内容时会出现异常,并告诉我发生了一些无法识别的错误。
可能出现什么问题?
char chArr [] = "1234567890";
CFile file;
file.Open("c:\\mfc.txt",CFile::modeCreate| CFile::modeNoTruncate| CFile::modeWrite | CFile::osNoBuffer | CFile::osWriteThrough);
file.Write(chArr,sizeof(chArr)); // exception
file.Flush();
file.Close();
答案 0 :(得分:4)
请参阅MSDN上对file buffering的讨论。
使用标记CFile::osNoBuffer
打开文件,或将标记FILE_FLAG_NO_BUFFERING
传递给CreateFile
,这是写入文件的一种特殊方式。它要求您用于写入文件的所有缓冲区都与内存中的扇区边界对齐,并且您只需要写入扇区大小的整数倍。除非你采取了特殊的步骤来对齐你正在传递的缓冲区(你没有在这里),并且至少写过512字节,除非设备静默忽略您的标志,否则它不太可能工作。我想您可能没有注意到WriteFile
返回了错误代码而不是抛出异常。
我会问:为什么要指定这个标志?它的使用是非常专业的,如果你只是做正常的日常文件I / O,比如写一个文本文件,那么你应该不指定这个标志。它可能会减慢您的程序速度,并使其更加复杂。我还建议您删除CFile::osWriteThrough
。
您知道:FILE_FLAG_NO_BUFFERING
的使用几乎专门用于编写必须直接访问磁盘的大量数据,例如实时数据记录或视频录制应用程序。 FILE_FLAG_WRITE_THROUGH
用于数据库日志文件之类的事务,每次写入后必须刷新事务正确性。在其他情况下禁用这些缓存和缓冲区通常会降低程序的速度。
这是another discussion遇到同样问题的人(虽然他们使用的是.NET,而不是C ++)。
编辑:感谢您提及尺寸要求Daryl。
答案 1 :(得分:1)
从MSDN文件缓冲讨论Doug在他的回答中提到..
文件访问大小(包括OVERLAPPED结构中的可选文件偏移量,如果指定)必须是多个字节,它是卷扇区大小的整数倍。例如,如果扇区大小为512字节,则应用程序可以请求读取和写入512,1024,1,536或2,048字节,但不能请求335,981或7,171字节。
读取和写入操作的文件访问缓冲区地址应该是扇区对齐的,这意味着在内存中的地址上对齐,这些地址是卷扇区大小的整数倍。根据磁盘的不同,可能不会强制执行此要求。
在我的系统上,改变......
char chArr[] = "1234567890";
到
char chArr[512] = "1234567890";
...摆脱了异常,但明显的问题是我现在正在向文件写一堆未初始化的垃圾字节。