写入文件时,CFile :: osNoBuffer标志会导致异常

时间:2010-09-24 07:52:03

标签: c++ winapi mfc

(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();

2 个答案:

答案 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";

...摆脱了异常,但明显的问题是我现在正在向文件写一堆未初始化的垃圾字节。