C++读取大文件

假设有一个10122164行int的文件(110 MB )

#include <iostream>
#include <fstream>
#include <cstdio>
#include <string>
#include <sstream>
#include <streambuf>
#include <windows.h>
using namespace std;
/**
 * 测速,输出时间(毫秒)
 * @param func 函数
 * @param args 参数
 */
template<typename T,typename ... Types>
void measure(T&& func,Types&& ... args) {
    LARGE_INTEGER m_nFreq;
    LARGE_INTEGER m_nBeginTime;
    LARGE_INTEGER nEndTime;
    QueryPerformanceFrequency(&m_nFreq); // 获取时钟周期
    QueryPerformanceCounter(&m_nBeginTime); // 获取时钟计数
    func(args...);
    QueryPerformanceCounter(&nEndTime);
    std::cout << (double)(nEndTime.QuadPart - m_nBeginTime.QuadPart) * 1000 / m_nFreq.QuadPart << "ms" << std::endl;
}
/**
 * 使用ifstream和cin
 */
void read_cin(){
    ifstream fin("E:\\C_plus_plus_Demo\\input.txt");
    if (!fin) {
       return;
    }
    int t;
    int cnt=0;
    while(fin>>t){
        //cout<<cnt++<<' '<<t<<endl;
    }
    fin.close();
}
/**
 * 使用freopen和cin
 */
void read_cin_freopen(){
    if(nullptr==freopen("E:\\C_plus_plus_Demo\\input.txt","r",stdin)){
        return;
    }
    int t;
    int cnt=0;
    while(cin>>t){
//        cout<<cnt++<<' '<<t<<endl;
    }
    fclose(stdin);
}
/**
 * 使用freopen和cin,并把同步关闭
 */
void read_cin_freopen_nosync(){
    std::ios::sync_with_stdio(false);
    if(nullptr==freopen("E:\\C_plus_plus_Demo\\input.txt","r",stdin)){
        return;
    }
    int t;
    int cnt=0;
    while(cin>>t){
//        cout<<cnt++<<' '<<t<<endl;
    }
    fclose(stdin);
}
/**
 * 使用freopen+scanf
 */
void read_scanf_freopen(){
    if(nullptr==freopen("E:\\C_plus_plus_Demo\\input.txt","r",stdin)){
        return;
    }
    int t;
    int cnt=0;
    while(~scanf("%d",&t)){
//        cout<<cnt++<<' '<<t<<endl;
    }
    fclose(stdin);
}
/**
 * 将char数组中的数字转为int数组
   假设读入的数字都是合法的
 * @param buf char数组
 * @param len 数组长度
 */
void char_buf2int_array(char *buf, int len){
    int t=0;
    char* p=buf;
    char* end=buf+len;
    bool flag=false;  //正负
    bool start=false;  //正在读数字
    int cnt=0;
    while(p!=end){
        if(*p==' '||*p=='\n'||*p=='\t'){
            if(flag)t=-t;
//            cout<<cnt++<<' '<<t<<endl;
            flag=false;
            t=0;
            start=false;
        }
        else if(*p=='+'||*p=='-'){
            start=true;
            flag=*p=='-';
        }
        else{
            start=true;
            t=t*10+(*p-'0');
        }
        p++;
    }
    //最后一个数字
    if(start){
        if(flag)t=-t;
//        cout<<cnt++<<' '<<t<<endl;
    }
}
/**
 * 一次性读取文件到char数组中,并转为int
 */
void read_all_char_buf(){
    ifstream fin("E:\\C_plus_plus_Demo\\input.txt",ios::in|ios::binary);
    if(!fin){
        return;
    }
    fin.seekg(0,ios::end);
    int length=fin.tellg();
    fin.seekg(0,ios::beg);
    char* buffer=new char[length];
    fin.read(buffer,length);
    fin.close();
    char_buf2int_array(buffer, length);
    delete[] buffer;
    buffer=nullptr;
}
/**
 * string转为int数组
 * 假设string中的数字都是合法的
 * @param buf string
 */
void string_buf2int_array(const string& buf){
   int t=0;
   bool flag=false;  //正负
   bool start=false;  //正在读数字
   int cnt=0;
   for(const char& c:buf){
       if(c==' '||c=='\n'||c=='\t'){
           if(flag)t=-t;
//            cout<<cnt++<<' '<<t<<endl;
           flag=false;
           t=0;
           start=false;
       }
       else if(c=='+'||c=='-'){
           start=true;
           flag=c=='-';
       }
       else{
           start=true;
           t=t*10+(c-'0');
       }
   }
   if(start){
       if(flag)t=-t;
//       cout<<cnt++<<' '<<t<<endl;
   }
}
/**
 * 一次性全部读取,并存入string,最后转为int数组
 */
void read_all_string(){
    ifstream fin("E:\\C_plus_plus_Demo\\input.txt",ios::in|ios::binary);
    if(!fin){
        return;
    }
    string buf((std::istreambuf_iterator<char>(fin)),
               std::istreambuf_iterator<char>());
    fin.close();
    string_buf2int_array(buf);
}
/**
 * 一次性全部读取到stringstream中,最后转为int数组
 */
void read_all_stringstream(){
    ifstream fin("E:\\C_plus_plus_Demo\\input.txt",ios::in|ios::binary);
    if(!fin) {
        return;
    }
    stringstream buffer;
    buffer << fin.rdbuf();
    fin.close();
    string buf(buffer.str());
    string_buf2int_array(buf);
}
int main() {
    cout<<"ifstream+cin ";
    measure(read_cin);
    cout<<"freopen+cin ";
    measure(read_cin_freopen);
    cout<<"freopen+cin+nosync ";
    measure(read_cin_freopen_nosync);
    std::ios::sync_with_stdio(true);
    cout<<"freopen+scanf ";
    measure(read_scanf_freopen);
    cout<<"ifstream+read 2 char* ";
    measure(read_all_char_buf);
    cout<<"ifstream+read 2 string ";
    measure(read_all_string);
    cout<<"ifstream+read 2 stringstream ";
    measure(read_all_stringstream);
    return 0;
}

测试环境win10+mingw+release模式

测试结果

ifstream+read 2 char* 60.3799ms

ifstream+read 2 stringstream 597.553ms

ifstream+read 2 string 687.233ms

freopen+cin+nosync 2103.91ms

ifstream+cin 2119.59ms

freopen+scanf 6370.44ms
freopen+cin 15141.7ms


 

发布了93 篇原创文章 · 获赞 83 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_39942341/article/details/104496988