分享

Windows环境下快速写入(磁盘)文件

 Qin Hantang 2012-06-02

Windows环境下快速写入(磁盘)文件

(2011-02-18 22:12:52)
标签:

秘笈

windows

写磁盘

分类: 备忘
今天无意中翻到去年一个项目中做的测试和试验,发现自己都快忘记了,还是记下来备忘吧。

我早说过,Windows是一个能出专家,也需要专家的平台,因为有太多的东西它在文档里不告诉你,或者告诉你的不是实情,需要你去摸索。那些摸索了又用小本本记下来的,或者拾到别人小本本的,就是专家。

在我用过的其它平台,UNIX/Linux/MacOS当然都用不着这么麻烦,你随便遍个C/C++程序写文件,不需要你自己做什么特别的优化,它的性能就非常好。但是,Windows不行,Windows下只有专家才知道怎么办。
可是这个项目必须在Windows下面,并且需要长时间(至少20分钟,超过1小时也正常)、稳定、快速的记录数据,在任何一秒都不能低于120MBps。

呵呵,这是文档上找不着的,我们也来做回专家吧。

三个要点:
    1.使用VirtualAlloc分配要写出数据使用的缓冲区
    2.预先分配文件的磁盘空间
    3.使用不带缓冲的文件读写操作
代码片断:
    // 3...使用不带缓冲的文件读写操作
    HANDLE hFileWrite = CreateFile(path, // name of the write
        GENERIC_WRITE, // open for writing
        0, // do not share
        NULL, // default security
        CREATE_ALWAYS, // overwrite existing
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING,  // normal file & no buffering
        NULL);                  // no attr. template
    // 2...预先分配文件的磁盘空间
    int64_t sz = file_size;
    SetFilePointer(hFileWrite, (long)sz, ((long*)&sz) + 1, FILE_BEGIN);
    SetEndOfFile(hFileWrite); // 会分配文件的存储空间
    SetFilePointer(hFileWrite, 0, NULL, FILE_BEGIN);
    // 1...使用VirtualAlloc分配要写出数据使用的缓冲区
    void *lpvBase = VirtualAlloc(
        NULL,                 // system selects address
        block_size, // size of allocation
        MEM_RESERVE | MEM_COMMIT,          // allocate reserved pages
        PAGE_READWRITE);       // protection = read/write

    if ( lpvBase == NULL ) {
        DWORD err = GetLastError();
        throw err;
    }
    char *buffer = (char*)lpvBase;
    for ( int i = 0; i < block_size; ++i)
        buffer[i] = i;
    // 4...写入本身很简单
    WriteFile(hFileWrite, buffer, block_size, &nWrite, NULL);
    // 5...记得清理
    VirtualFree(
        lpvBase,       // base address of block
        0,             // bytes of committed pages
        MEM_RELEASE);  // decommit the pages
    CloseHandle(fh);
其中,起决定性作用的是“1.使用VirtualAlloc分配要写出数据使用的缓冲区”。
在我的测试环境中(硬盘ST3320620AS,格式化为NTFS文件系统,默认分配单位大小),写入文件的速度3项全做时,平均文件写入速度(文件大小8G,写入块大小32M)为66MBps,甚至超过了我们测试用的专门磁盘工具在这个磁盘上的性能;只做第一项,然后直接用C++的ofstream::write()写出时(文件和块大小不变),平均速度为60MBps。
三项优化都不做时,不论用什么办法写,平均速度最多30MBps。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多