c/c++拷贝文件的4种方式 复制

c/c++拷贝文件的4种方式

简单列举了4种,还有其他方法,但估计性能相差不会太大。c风格的fopen,fread,fwrite最快。

结论

方法1:

使用fstream的rdbuf

方法2:

使用fstream的read,write

方法3:

使用c风格的fopen,fread,fwrite

方法4:

使用filesystem库的copy函数

//    bool ans = copyFile1(origin_path, target_path);
    //1.67116s
    //1.66836s
    //1.69654s
//    bool ans = copyFile2(origin_path, target_path);
    //0.964877s
    //1.85492s
    //1.56042s
    //1.5414s
//    bool ans = copyFile3(origin_path, target_path);
    //0.538489s
    //0.543495s
    //0.517471s
    bool ans = copyFile4(origin_path, target_path);
    //1.69654s
    //1.67552s
    //1.71977s

可以看出使用fstrean的rdbuf和使用filesystem库的copy函数是最慢的。

使用fstream的read,write会稍微加快复制的速度。

速度最快的是c风格的fopen,fread,fwrite。

测试方式:

首先创建一个test文件夹。

每次运行代码测试前,先将test文件夹清空,随机复制进去一个几十m到200m的文件夹(为了避免在磁盘的同一个位置重复写入一个文件导致影像测试速度的真实性),然后运行代码(这样每次用代码复制过去的磁盘位置都不一样)。

测试代码

c++17版本:

#include<iostream>
#include<string>
#include<io.h>
#include<Windows.h>
#include<thread>
#include<vector>
#include<set>
#include<stdio.h>
#include<fstream>
#include<time.h>
#include<filesystem>
#include<chrono>

using namespace std;
using namespace chrono;
namespace fs = filesystem;

bool copyFile1(string origin_file_path, string target_file_path)
{
    ifstream infile;
    infile.open(origin_file_path.c_str(), ios::binary|ios::in);

    ofstream outfile;
    outfile.open(target_file_path.c_str(), ios::binary|ios::out);

    if(!infile||!outfile)
        return FALSE;

    outfile << infile.rdbuf();

    infile.close();
    outfile.close();
    return TRUE;
}

bool copyFile2(string origin_file_path, string target_file_path)
{
    ifstream in(origin_file_path.c_str(), ios::binary|ios::in);
    ofstream out(target_file_path.c_str(), ios::binary|ios::out);
    if (!in||!out)
        return FALSE;
    const int buffsize = 1024;
    char flush[buffsize];
    while(!in.eof()){
        in.read(flush, buffsize);
        out.write(flush, in.gcount());
//        printf("%d\n", in.gcount());
    }
    in.close();
    out.close();
    return TRUE;
}

bool copyFile3(string origin_file_path, string target_file_path)
{
    FILE *infile, *outfile;
    infile=fopen(origin_file_path.c_str(), "rb");
    outfile=fopen(target_file_path.c_str(), "wb");
    if(infile==NULL||outfile==NULL)
        return FALSE;
    const int buffsize=2048;

    char buff[buffsize];
    int read_count=0;
    while(!feof(infile))
    {
        read_count = fread(buff,sizeof(char),buffsize,infile);
        fwrite(buff,sizeof(char),read_count,outfile);
    }
    fclose(infile);
    fclose(outfile);
    return TRUE;
}

bool copyFile4(string origin_path, string target_path)
{
    error_code ec;
    fs::copy(origin_path.c_str(), target_path.c_str(), fs::copy_options::recursive, ec); // ¸´ÖÆĿ¼£¨µÝ¹é£©
    return ec.value()==0;
}

int main()
{
    string origin_path = "D:\\software\\burpsuite\\burpsuite_community_windows-x64_v2020_12.exe";
    string target_path = "F:\\test\\burpsuite_community_windows-x64_v2020_12.exe";
    auto start = system_clock::now();
//    bool ans = copyFile1(origin_path, target_path);
    //1.67116s
    //1.66836s
    //1.69654s
//    bool ans = copyFile2(origin_path, target_path);
    //0.964877s
    //1.85492s
    //1.56042s
    //1.5414s
//    bool ans = copyFile3(origin_path, target_path);
    //0.538489s
    //0.543495s
    //0.517471s
    bool ans = copyFile4(origin_path, target_path);
    //1.69654s
    //1.67552s
    //1.71977s
//    cout<<ans<<endl;
    auto end   = system_clock::now();
    auto duration = duration_cast<microseconds>(end - start);
    cout << double(duration.count()) * microseconds::period::num / microseconds::period::den<< "s" << endl;
    return 0;
}
文章目录