如何使用 C++ 程序快速地将文件从一个位置复制到另一个位置?

How to copy a file from one location to another in a fast way with C++ program?

我试图理解复制命令背后的代码,该命令将文件从一个地方复制到 other.I 学习了 C++ 文件系统基础知识并为我的任务编写了以下代码。

#include<iostream>
#include<fstream>

using namespace std;

main()
{
    cout<<"Copy file\n";
    string from,to;
    cout<<"Enter file address: ";
    cin>>from;
    ifstream in(from,ios::in | ios::binary);
    if(!in)
    {
        cout<<"could not find file "<<from<<endl;
        return 1;
    }
    cout<<"Enter file destination: ";
    cin>>to;
    ofstream out(to,ios::out | ios::binary);
    char ch;
    while(in.get(ch))
    {
        out.put(ch);
    }
    cout<<"file has been copied\n";
    in.close();
    out.close();
}

虽然此代码有效,但比我的 OS 的复制命令慢得多 windows.I 想知道如何使我的程序更快以减少我的程序时间和时间之间的差异我的 OS 的复制命令时间。

您已正确打开文件进行二进制读取和二进制写入。但是,不要读取字符(这在二进制格式中没有意义),而是使用 istream::read and ostream::write.

一次读取一个字节会在函数调用中浪费大量时间...使用更大的缓冲区:

char ch[4096];
while(in) {
    in.read(ch, sizeof(ch));
    out.write(ch, in.gcount());
}

(您可能想添加更多错误处理,例如 out 可能会进入错误状态等)

(据报道,最像 C++ 的方法 here,但利用了 streambuf 通常初学者很少有理由知道的功能,而且对我来说也没有多少指导意义)

就像其他答案所说的那样,使用更大的缓冲区。我会选择 1MB。 但还有更多。

此外,避免使用流库和文件。他们缓冲数据,所以你得到 2 个 memcpy 调用而不是 1 个。 禁用流上的缓冲可以获得类似的结果,但我认为你最好直接使用系统调用。

还有最后一件事,在 "do it yourself" 前面。您必须检查读取和写入调用中的 return 值。他们可能 read/write 字节数比您要求的少。

如果你可以管理一个循环缓冲区,你应该在函数 return 短时切换 read/wrote...磁盘可能更适合读取或写入,所以没有必要浪费时间等待而不是切换到你必须做的另一件事。

现在您可能想要探索的最后一件事 - 查看 sendfile 系统调用。它旨在通过在内核中执行所有复制并避免上下文切换和 memcpys 来加速 Web 服务器,但如果它使用两个磁盘文件描述符,则可以在这里使用。