C++大ファイルコードの読み書き

7291 ワード

読み書きが4 Gより大きいファイル、テストファイルはvs 2013インストールパッケージ、サイズは7.08 Gです.プログラムは64 bitです.
#include "stdafx.h"
#include 
#include 
#include 
#include 
using namespace std;

const char   FILE_RD = "d:\\vs2013.iso";//   
const char   FILE_WR = "d:\\vs2013_bak.iso";//      
const size_t WR_SIZE = 1024*1024*10;//       ,   10M
void hugefile_rw()
{
        FILE* stream_rd,*stream_wr;
        size_t num_read,num_written;
        int rw_cnt = 0;
        long long offset = 0;
        if(0 != fopen_s(&stream_wr,FILE_WR,"wb")){//          
            return;
        }
        DWORD dStart = GetTiclCount();
        char *buf = new char[WR_SIZE];
        if(0 == fopen_s(&stream_rd,FILE_RD,"rb")){
            while(!feof(stream_rd)){
                rw_cnt++;
                // 
                num_read = fread(buf,sizeof(char),WR_SIZE,stream_rd);
                if(0==num_read) break;
                offset += num_read;//    
                _fseeki64(stream_rd,offset,SEEK_SET);
                // 
                num_written = fwrite(buf,sizeof(char),num_read,stream_wr);
                _fseeki64(stream_wr,offset,SEEK_SET);
                cout<<"Cnt = "<",num_read = "<",num_written = "<< num_written;
            }
        }
        DWORD dEnd = GetTiclCount();
        cout<<"     = "<< (dEnd - dStart)/1000<<"s"<//    
        delete []buf;
        fclose(stream_rd);
        fclose(stream_wr);      
}

int main(int argc,_TCHAR* argv[])
{
    hugefile_rw();
    getchar();
    return 0;
}
//if(0 == ferror(stream_wr)){
    //ok
//}

freadで「.dat」ファイルを読むときに完全なファイルを読むことはできません.0 x 1 Aまで読むとfreadは終わりだと思います.textモードでファイルを開くと、システムのデフォルトCTRL+Zはファイル終了文字であり、0 x 1 AはCTRL+ZのASCIIコードである.ファイルを以下の形式で開きます.datafile = fopen(“whatever.dat”, “rb”); これで以上の問題を解決できます!
テストは可能ですが、速度はあまりよくありません.マルチスレッドまたはメモリマッピングファイル方式を考慮して効率を向上させることができます.1 Gを読み書きするたびに効率が低く、100 Mがよく、10 Mがもっとよく、1 M、512 kの速度差が少なく、局所的な原理、キャッシュの原因かもしれません.
fstreamの方法でも使用できます.コードは次のとおりです.
#include "stdafx.h"
#include 
#include 
#include 
#include 
using namespace std;
const char   FILE_RD = "d:\\vs2013.iso";//   
const char   FILE_WR = "d:\\vs2013_bak.iso";//      
const size_t WR_SIZE = 1024*1024*10;//       ,   10M

void hugefile_rw2()
{        
        DWORD dStart = GetTiclCount();
        fstream in(FILE_RD,ios::in  | ios::binary);
        fstream out(FILE_WR,ios::out  | ios::binary);
    //  ifstream in(FILE_RD,ios::in  | ios::binary);
    //  ofstream out(FILE_WR,ios::out  | ios::binary);
        DeleteFileA(FILE_WR);       
        char *buf = new char[RD_SIZE];       
        while(!in.eof()){

             std::streamsize num_read = in.read(rd_buf,RD_SIZE).gcount();
             if(0==size) break;
             in.seekg(size,ios::cur);
             out.write(rd_buf,size);
             out.seekg(size,ios::cur);
        }        
        DWORD dEnd = GetTiclCount();
        cout<<"Time = "<< (dEnd - dStart)/1000<in.close();
        out.close();
}
int main(int argc,_TCHAR* argv[])
{
    hugefile_rw2();
    getchar();
    return 0;
}

テストによりfstreamはfwriteよりも効率が低いことが分かった.