我想用内存映射和直接读取文件分别实现MD5算法。
众所周知,该算法是线性复杂度,文件的读取可能成为效率的瓶颈。
以前曾写过CRT版本的,效率比我在windows下使用的WinMD5略低。
内存映射读取MapViewOfFile
第一步先打开文件,推荐使用CreateFile而不是OpenFile。msdn上OpenFile可以查到:
Note Only use this function with 16-bit versions of Windows. For newer applications, use the CreateFile function."
我们只需要读文件
文件查找失败会返回 INVALID_HANDLE_VALUE。
第二步是建立文件映射
由于不需要别的映射,这里让 lpName = NULL
失败会返回NULL。
第三步把文件的某个片段映射到内存空间
对于小的文件直接一次映射到内存就行了,但是4G大小的文件,你会发现这一步会映射失败,32位地址允许的内存最多是2G,所以我们要分多次映射,每次取的offset必须是系统allocation granularity的整数倍。
我的是笔记本,操作系统Vista下的granularity = 65536。大多数的PC机应该都是这个数值。
令uPos 是偏移量,STEP是每次取出映射的长度
失败会返回 NULL。
获取文件大小,注意如果文件大小超过2G,需要GetFileSize的第2个参数作为文件大小的高位
完整代码如下
直接文件读取ReadFile
大致上差不多,有个优化速度的地方就是不要每次读取64个byte。我是每次读取1024×64个byte,然后分1024次处理
这样速度上快一些,我原来CRT版本的就是这么做的。
完整代码如下
两种方法的速度比较
都不是很理想,对一个4G的大文件直接读取速度要快一些,大约260s。
500M左右的文件也是后者快一点点。没有感觉到内存映射的优势:(
内存映射有个小地方要注意的是:如果文件是0 byte的话,CreateFileMapping这步会失败,需要另外处理。
不过实际中不用考虑这个。