windows文件读取效率对比

readfile1.cpp是使用内存映射文件读取文件,readfile2.cpp是普通ReadFile

readfile1.cpp代码

 char buf[10001];
    const char *env = getenv("DATA_DIR");
    char wsp[255];
    sprintf(wsp, "%s/demo.dbf", env);
    //const char *wsp = "wan.log";
    int a = GetTickCount();
    HANDLE h = CreateFile(wsp, GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    HANDLE h2 = CreateFileMapping(h, NULL, PAGE_READONLY, 0, 0, NULL);
    char *p = (char *)MapViewOfFile(h2, FILE_MAP_READ, 0, 0, 0);
    for(int j = 0; j < 1000; j++)
    {
        for(int i = 0 ; i < 1000; i++)
        {
            memcpy(buf, p + i*10000, 10000);
        }
    }
    printf("time used %d\n", GetTickCount() - a);
    buf[10000] = 0;
    //printf(buf);
    UnmapViewOfFile(p);
    CloseHandle(h2);
    CloseHandle(h);
    scanf("%s", buf);
    return 0;


 readfile2.cpp代码

 char buf[10001];
    const char *env = getenv("DATA_DIR");
    char wsp[255];
    sprintf(wsp, "%s/demo.dbf", env);
    int a = GetTickCount();
    ULONG r;
    HANDLE h = CreateFile(wsp, GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    for(int j = 0; j < 1000; j++)
    {
        for(int i = 0 ; i < 1000; i++)
        {
    		SetFilePointer(h, 10000*i, 0, FILE_BEGIN);
    		ReadFile(h, buf, 10000, &r, 0);
        }
    }
    printf("time used %d\n", GetTickCount() - a);
    buf[10000] = 0;
    CloseHandle(h);
    scanf("%s", buf);
    return 0;

性能对比

1,任务管理器中各项指标

 

2,速度对比


任务管理器中各项指标性能对比:随机访问时1比2快多了
         2.1 如果把2中SetFilePointer注释掉

结论
 

1.频繁的SetFilePointer与ReadFile会非常费劲。就算SetFilePointer调用是多余的。
 
2.去掉SetFilePointer后与2原来io读取量对比可知,ReadFile其实本身就有缓存;

SetFilePointer会使ReadFile的缓存机制失去作用。
 
3.使用内存映射随机读取文件会比ReadFile快多了,但是顺序读取文件时ReadFile快(估计是内存映射机制有太多的页面错误,性能有损耗)
 
4.内存映射文件其实就是建立起虚拟内存与物理磁盘间的映射关系。访问建立起内存映射文件的虚拟内存时,如果那块文件没有装进内存,会引起缺页中断,自动把那部分文件装进内存以供访问。因此1的页面错误比2多很多。但是1的io读取量又比2少很多,推测是由缺页中断导致的io读取并没有在任务管理器体现。
 
5.用内存映射文件读文件,内存哪里去了?为何1跟2比他不比2占内存?看看1的缺页次数与2对比,多了2453次,在windows上默认一个页面就是4k大小,2453*4k大约就是9.5m其实大约就是10m,就是我实际读了这么多的文件,这解释了说明了1.其实内存映射文件不占内存,2.io量虽然在io读取字节里面看不出来,但是在缺页次数上面可以推算出来。

 

Windows C中实现大文件的读写封装可以通过以下步骤来完成。 首先,需要使用Windows提供的API函数来操作文件。其中比较常用的函数有CreateFile、ReadFile和WriteFile等。CreateFile函数用于打开文件并返回一个文件句柄,可根据需要设置打开模式、访问权限等。ReadFile函数用于从文件读取数据,可以指定要读取的字节数。WriteFile函数用于向文件中写入数据,同样可以指定要写入的字节数。 其次,可以封装一个读取文件的函数。在该函数中,先通过CreateFile函数打开需要读取的大文件,并获取文件句柄。然后通过循环调用ReadFile函数读取文件内容,直到读取完整个文件。在读取过程中,可以使用一个缓冲区来存储每次读取的数据,避免频繁的文件IO操作。最后,关闭文件句柄,并释放相关资源。 再次,可以封装一个写入大文件的函数。在该函数中,先通过CreateFile函数创建要写入的大文件,并获取文件句柄。然后通过循环调用WriteFile函数将数据写入文件,直到完成全部数据的写入。同样,可以使用一个缓冲区来存储每次要写入的数据,减少文件IO操作次数。最后,关闭文件句柄,并释放相关资源。 此外,为了提高大文件读写的效率,还可以采用多线程或异步IO的方式来并行读写大文件。通过将文件分割成多个块,每个块由独立的线程或IO操作来读写,可以同时进行多个读写操作,加快文件读写速度。 综上所述,通过使用Windows提供的API函数,结合封装的读写函数以及多线程或异步IO的方式来实现大文件的读写封装,可以提高文件IO效率,满足对大文件处理的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值