繁体   English   中英

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

[英]CFile::osNoBuffer flag causes exception when writing to file

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

请参阅有关MSDN上文件缓冲的讨论。

使用标志CFile::osNoBuffer打开文件,或将标志FILE_FLAG_NO_BUFFERING传递给CreateFile ,是写入文件的一种特殊方法。 它要求将用于写入文件的所有缓冲区与内存中的扇区边界对齐,并且仅写入扇区大小的整数倍。 除非您已采取特殊步骤来对齐要传递的缓冲区(您在此处没有),并且还至少写入了512个字节,否则除非设备静默忽略您的标志,否则它将无法正常工作。 我认为您可能没有注意到WriteFile返回错误代码而不是引发异常。

我会问:为什么要指定此标志? 它的使用是相当专业的,如果你只是在做正常的日常文件I / O,就像写一个文本文件,那么你应该指定该标志。 它可能会减慢您的程序的速度,并使其变得更加复杂。 我还建议您删除CFile::osWriteThrough

就像您知道的那样: FILE_FLAG_NO_BUFFERING几乎仅用于写大量必须直接进入磁盘的数据,例如实时数据记录或视频记录应用程序。 FILE_FLAG_WRITE_THROUGH用于诸如数据库日志文件之类的事情,必须在每次写入后刷新它们,以确保事务的正确性。 在其他情况下,禁用这些缓存和缓冲区通常会降低程序速度。

这是另一个讨论相同问题的人的讨论 (尽管他们使用的是.NET,而不是C ++)。

编辑:感谢您提到大小要求达里尔。

在MSDN文件缓冲讨论中,道格在回答中提到了..

  • 文件访问大小(包括OVERLAPPED结构中的可选文件偏移)(如果已指定)必须为字节数,该字节数是卷扇区大小的整数倍。 例如,如果扇区大小为512字节,则应用程序可以请求512、1,024、1,536或2,048字节的读写,但不能请求335、981或7,171字节的读写。

  • 用于读取和写入操作的文件访问缓冲区地址应按扇区对齐,这意味着在内存中的地址上对齐,该地址是卷扇区大小的整数倍。 根据磁盘的不同,可能不会强制执行此要求。

在我的系统上,正在更改...

char chArr[] = "1234567890";

char chArr[512] = "1234567890";

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM