东源县住房和城乡建设部网站,搜索引擎排名规则,景县做个油管的网站怎么做,全国信息企业查询系统官网上一篇介绍了一种常见的文件处理方法(可优化为#xff1a;分次读取文件#xff0c;但要满足根据行号能快速索引该行内容时会遇到麻烦),所以此片我将介绍另一种更高效#xff0c;实用#xff0c;并对本进程的内存空间地址消耗小的方法#xff01; 一. 预备知识
1#xff…上一篇介绍了一种常见的文件处理方法(可优化为分次读取文件但要满足根据行号能快速索引该行内容时会遇到麻烦),所以此片我将介绍另一种更高效实用并对本进程的内存空间地址消耗小的方法 一. 预备知识
1. Windows编程处理文件的相关接口
ACreateFile();
BReadFile();
cWriteFile();
dCloseHandle();
2. 文件映射相关接口:
A) CreateFileMapping
BMapFIleOfView
COpenFileMapping
DCloseHandle
3注
由于以上接口MSDN以及网上的牛人们已经给了详细的介绍了这里我只累叙 一下MapViewOfFile()第四个参数 DWORD dwFileOffsetLow
此偏移量必须64k对齐,可能是由于便于内存管理得快速访问才做此限定如下代码 LARGE_INTEGER liOffset {};liOffset.QuadPart lpLineInfo-liHeadCharOffset.QuadPart (~MemmoryHex_64k);DWORD DValue DWORD(lpLineInfo-liHeadCharOffset.QuadPart - liOffset.QuadPart);char *lpHeadSrc (char*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, liOffset.HighPart, liOffset.LowPart, (DValue lpLineInfo-LineCount));二.思想1) 在处理文件过程中我们一般采用的方法是分块如每次512k读取文件数据进行处理这样做的目的如下
A申请小块内存速度快
B可以不用New动态创建存数据的Buffer而是直接可以用栈存储次Buffer降低内存泄漏的风险
C若一次申请一块较大的地址空间(512M)那你还让其他线程工作吗一个进程中的多个线程是共用同一块地址空间的
对于B有朋友会说那可以将进程中允许访问的栈空间调大1G,但这样是有风险的比如你在编写递归代码时出错可能导致死循环由于堆设得过大导致要许久才会导致栈溢出增加我们调式bug得难度而当栈的空间地址范围较小时函数调用栈很快就会溢出Buf易复现就便于修改了 2当文件大小在允许访问内(我的机器24G),将文件内容映射到内存上对文件的访问速率相当于内存的读取率
A注我的公司开发机Win7 64位16G运行内存15G虚拟内存
B由于映射的内存块可以被本机的其他进程访问所以我们通常也称之为共享内存 3每次映射小块文件数据到次进程的地址空间上进行处理(与上篇中处理方式一样) DWORD RelMapMemorySize DWORD((liTotalFileSize.QuadPart - liHandleFileSize.QuadPart DValue EachMapMemorySzie) ? EachMapMemorySzie : (liTotalFileSize.QuadPart - liHandleFileSize.QuadPart DValue));lpHeadSrc (char*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, liOffset.HighPart, liOffset.LowPart, RelMapMemorySize);4根据行号索引该行内容相当于随机访问数组的速率
相交与上篇此篇存储每一行信息的数据结构有所改变如下 typedef struct LINE_INFO{LARGE_INTEGER liHeadCharOffset;INT32 LineCount;}LINE_INFO;A我们根据liHeadCharOffset算出映射时候的偏移量
B注意我们必须保证此低字节的偏移量必须64K对其所以这里必须先对liHeadCharOffset进行处理
a映射偏移量首先对此值取商 LARGE_INTEGER liOffset {};liOffset.QuadPart lpLineInfo-liHeadCharOffset.QuadPart (~MemmoryHex_64k);DWORD DValue DWORD(lpLineInfo-liHeadCharOffset.QuadPart - liOffset.QuadPart);b处理时再加上我们做商时舍弃的差值 char *lpHeadSrc (char*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, liOffset.HighPart, liOffset.LowPart, (DValue lpLineInfo-LineCount));if (NULL lpHeadSrc){m_lpHLog-TraceLog(Error(%s.%d): MapViewOfFile Failed!\r\n, __FUNCTION__, __LINE__);return FALSE;}char *lpHead lpHeadSrc DValue;5关于倒叙写文件相信聪明的朋友也能按照上述方案分块映射分块写了,就不在累叙了 6其余处理之处应与上一篇类似(实际已近不记得了因为此代码是上个月初写的我上一篇的代码是这个月初写的。。。)也不过多介绍了 三. 最后上一下运行图 注本机是在是找不到大的文本文件当明显速度比上一篇中的处理速度快且我在开发机上测试时Release模式下(不包含最后逆序写文件)文件处理速度达到100M/s
这数据也许不准因为Windows操作系统对开机第一次读取文件比以后读取文件速率慢很多据说与什么预读和磁盘命中率有关总之就是比文件映射处理文件速率比较快 此文件80M左右Debug模式下给我的感觉基本是1s左右我的本本是5年前卖的 最后看了下时间如右2016/08/05 22:40:43.407 Time is 1357(单位是ms) 四如果对源码有兴趣得朋友可以点击这里下载源码 五如发现我上述观点有错误的地方希望朋友不啬指出方便大家共同提升谢谢