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

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

本问题已经有最佳答案,请猛点这里访问。

我试图理解复制命令背后的代码,它将文件从一个地方复制到另一个地方。我研究了c ++文件系统的基础知识,并为我的任务编写了以下代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<iostream>
#include<fstream>

using namespace std;

main()
{
    cout<<"Copy file
"
;
    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
"
;
    in.close();
    out.close();
}

虽然这段代码有效,但比我的操作系统的复制命令慢得多。我想知道如何让我的程序更快,以减少我的程序的时间和我的操作系统的复制命令时间之间的差异。


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

1
2
3
4
5
char ch[4096];
while(in) {
    in.read(ch, sizeof(ch));
    out.write(ch, in.gcount());
}

(您可能希望添加更多错误处理,例如out可能会处于错误状态等)

(这里报道了大多数C ++ - ish方式,但是利用了通常初学者很少有理由知道的streambuf功能,对我来说也不那么有启发性)


像其他答案一样,使用更大的缓冲区。我要去1MB。
但还有更多内容。

此外,避免流lib和FILE的东西。它们缓冲数据,因此您可以获得2个memcpy调用而不是1。
禁用流上的缓冲可以获得类似的结果,但我认为你最好直接使用系统调用。

最后一件事,就是"自己动手"。您必须检查读写调用的返回值。它们可能读取/写入的字节数比您要求的少。

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

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


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