在大型项目开发中,经常会遇到需要对文件进行各种操作的情况。这些操作可能涉及到文件指针、Windows内核句柄,或者是标准库中的文件流接口。随着项目规模的扩大,这些操作函数会变得越来越分散,管理起来也变得越来越复杂。为了解决这个问题,"WinFile"项目应运而生,它将所有与文件相关的操作集中到一个统一的接口中。
"WinFile"最初只是一个简单的函数集合,用于在MS-Windows系统上执行文件操作。随着时间的推移,它不断发展壮大,收集了更多的函数和技巧。例如,虽然可以直接调用SDK函数如"CopyFile"来复制文件,但很少有人记得使用"CopyFileEx"时可以利用的所有额外选项。"WinFile"类将这些技巧集中在一起,使得不必在代码中到处寻找。
要使用"WinFile"类,最好的文档就是项目中的"WinFile.h"接口文件。在那里,可以找到所有的方法和枚举参数。以下是"WinFile"类可以执行的一些操作的简要概述:
在开发过程中,遇到了一个性能瓶颈。在文本转换模式下读取字符串时,将文件中的"\r\n"转换为单个"\n"的过程非常慢。在第一个版本中,这个过程比使用"fgets(buffer,count,FILE)"慢了10倍以上。决定自己编写一个缓冲区缓存来解决这个问题。"WinFile"类的第一个缓存版本可以轻松地为读取操作读取缓冲区,并返回缓存的字符串版本。这大大提高了性能,即使是在SSD系统上也是如此。在传统的HDD上,性能提升更加明显。
真正的挑战在于,不仅要能够写入缓存,还要在进行随机访问时同步。在随机访问模式下读取和写入意味着操作系统的"真实"文件指针与缓存缓冲区中的文件指针不同步。因此,必须始终调整以刷新缓冲区并重新同步文件指针。
在所有功能都正确工作之后,对与其他文件访问方法的性能比较产生了兴趣。新生儿与"ifstream"接口相比如何呢?以下是比较表(从"main.cpp"中的测试程序编译得出,使用"HPFCounter"进行时间测量,可在https://github.com/edwig/marlin找到)。
除了SSD比HDD快之外,从这个测试中学到的是,创建的WinFile缓存比从"fgets" FILEs读取快得多(至少快两倍),而且比标准库中的ifstream快3倍!当多次运行这个测试时,这些时间相当一致。
这是一个决定性的比较吗?当然不是。有很多因素可以影响结果,比如驱动器的类型、正在读取或写入的文件类型等等。标准库的爱好者会指出,可以通过使用(ifstream).rdbuf()->pubsetbuf(buf,size)方法来增加ifstream的缓冲区大小以获得更好的性能。可以自己尝试,虽然这在像Apple-OS和Linux这样的类Unix操作系统上确实可以提高读取性能,但在MS-Windows上却没有任何效果。但也许有人会发现惊喜...
请和平相处,不要引发争论。还有很多其他关于读写文件的优化方法。从未打算引发一场争论。