我们如何写以FILE_FLAG_NO_BUFFERING打开的文件的结尾?
我正在使用VB6和Win32 API将数据写入文件,此功能用于导出数据,因此,对磁盘的写入性能是我考虑的关键因素。因此,在通过调用CreateFile来打开文件时,我正在使用FILE_FLAG_NO_BUFFERING
和FILE_FLAG_WRITE_THROUGH
选项。
FILE_FLAG_NO_BUFFERING
要求我使用自己的缓冲区并将数据以磁盘扇区大小的倍数写入文件,通常,这没有问题,除了最后一部分数据(如果不是扇区大小的精确倍数)将包括字符零填充文件,一旦写入最后一个块以不包括这些字符零,如何设置文件大小?
我可以使用SetEndOfFile
,但这需要我关闭文件并重新打开它,而不必使用FILE_FLAG_NO_BUFFERING
。我见过有人在谈论NtSetInformationFile
,但是我找不到在VB6中使用和声明它的方法。 SetFileInformationByHandle可以完全满足我的要求,但是仅在Windows Vista中可用,我的应用程序需要与Windows的早期版本兼容。
解决方案
我不确定,但是我们确定设置FILE_FLAG_NO_BUFFERING和FILE_FLAG_WRITE_THROUGH可以为我们带来最佳性能吗?
它们肯定会导致数据尽快到达磁盘,但是这种事情实际上并没有帮助提高性能,而只是提高了日志文件之类的可靠性,如果我们希望日志文件尽可能完整,碰撞。
对于我们所描述的数据导出例程,允许操作系统缓冲数据可能会导致更好的性能,因为写入将与其他磁盘活动一致进行计划,而不是强制磁盘在每次写入时都跳回到文件中。
如果没有这些选项,为什么不对代码进行基准测试呢?保留0字节填充逻辑以使其成为公平的测试。
如果事实证明跳过这些选项的速度更快,则可以删除0填充逻辑,并且文件大小问题会自动修复。
我相信SetEndOfFile是唯一的方法。
我同意Mike G.的建议,无论有没有FILE_FLAG_NO_BUFFERING,我们都应使用自己的代码。在现代操作系统上的Windows文件缓冲非常有效。
好吧,我很惊讶!使用Windows缓冲而不是自己完成所有操作,速度要快得多。我一直在写一个1Gb文件进行测试,使用我自己的缓冲区,而FILE_FLAG_NO_BUFFERING
和FILE_FLAG_WRITE_THROUGH
选项平均花费21.146秒,而没有那些设置,并且使用Windows缓冲区,平均时间降至13.53秒,这已经结束了快30%!
自我注意:无需重新发明轮子。 ;-)
谢谢"迈克G"的快速准确的回答。同时也感谢" gabr",现在完全不必理会" SetEndOfFile"。