1. 程式人生 > >多緩衝區讀寫檔案

多緩衝區讀寫檔案

 

使用 OVERLAPPED 來讀寫大檔案還錯,如果是小檔案效能不是特別好 , 這個僅僅是自己電腦的測試.

用多緩衝區來讀寫會比較快

 

一個例子:

const int __BUFFSIZE = 8192;            //存放大小
const int __LEN = 10;                   //10個緩衝區
struct
{
    struct{
        char *data;                    //讀入的地方
        int readbytes;                 //讀入位元組數
    }buff[__LEN];                      
    HANDLE empty;                     //2個訊號量
    HANDLE stored;
} share;

unsigned int __stdcall read_thread(void* param)
{
    HANDLE hFile = (HANDLE)param;
    int i = 0;
    DWORD bytesReaded = 0;
    DWORD ret = 0;
    while(1)
    {
        WaitForSingleObject(share.empty,-1);

        //讀取__BUFFSIZE 到緩衝區
        ret = ReadFile(hFile,share.buff[i].data,__BUFFSIZE,&bytesReaded,NULL);

        //每次把讀取的位元組數記錄下來, 如果是0 則讀完
        share.buff[i].readbytes = bytesReaded;

        if(!ret){
            //出錯的情況,把readbytes =0, 用於釋放寫執行緒
            share.buff[i].readbytes = 0;
            ReleaseSemaphore(share.stored,1,0);
            cout << "error" << endl;
            break;
        }
        //讀完了
        if(0 == bytesReaded){
                ReleaseSemaphore(share.stored,1,0);
                break;
        }
        //重置索引
        if(++i > __LEN)
            i = 0;
        ReleaseSemaphore(share.stored,1,0);
    }
    return 0;
}
unsigned int __stdcall write_thread(void* param)
{
    HANDLE hFile = (HANDLE)param;
    int i = 0;
    while(1)
    {
        WaitForSingleObject(share.stored,-1);
        if(0 == share.buff[i].readbytes ){
            break;
        }
        cout << share.buff[i].data << endl;
        if(++i > __LEN)
            i = 0;
        ReleaseSemaphore(share.empty,1,NULL);
    }
    return 0;
}

void test_nbuff(const TCHAR* path)
{
    HANDLE hFile = CreateFile(path,GENERIC_READ,
                              FILE_SHARE_READ|FILE_SHARE_WRITE,
                              NULL,OPEN_EXISTING,
                              NULL,NULL);
    
    //初始化, 第三個引數其實可以填 __LEN . 
    share.empty = CreateSemaphore(NULL,__LEN,100,NULL); //用於讀執行緒, 一開始就10個訊號量
    share.stored = CreateSemaphore(NULL,0,100,NULL);    //用於寫執行緒

    
    for(int i = 0; i < __LEN; ++i){
        share.buff[i].data  = new char[__BUFFSIZE];
        share.buff[i].readbytes = 0;
    }

    HANDLE t_read = (HANDLE)_beginthreadex(0,0,read_thread,(void*)hFile,0,0);
    HANDLE t_write = (HANDLE)_beginthreadex(0,0,write_thread,(void*)hFile,0,0);

    WaitForSingleObject(t_read,-1);
    WaitForSingleObject(t_write,-1);
    cout << "done" << endl;

}