我正在尝试理解复制命令背后的代码,该代码将文件从一个地方复制到另一个地方。我研究了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();
}
虽然这段代码有效,但比我的操作系统的复制命令慢得多。我想知道如何让我的程序更快,以减少我的程序的时间和我的操作系统的复制命令时间之间的差异。 / p>
答案 0 :(得分:1)
一次读取一个字节会在函数调用中浪费大量时间...使用更大的缓冲区:
char ch[4096];
while(in) {
in.read(ch, sizeof(ch));
out.write(ch, in.gcount());
}
(您可能需要添加更多错误处理,例如out
可能会处于错误状态等)
(大多数C ++ - ish方式报告here,但利用了streambuf
功能,这些功能通常是初学者很少有理由知道的,对我来说也不那么有启发性。
答案 1 :(得分:0)
您已正确打开文件以进行二进制读取和二进制写入。但是,请使用istream::read和ostream::write,而不是阅读字符(二进制格式无效)。
答案 2 :(得分:0)
像其他答案一样,请使用更大的缓冲区。我要去1MB。 但还有更多内容。
另外,请避免使用流lib和FILE。它们缓冲数据,因此您可以获得2个memcpy调用而不是1。 禁用流上的缓冲可以达到类似的效果,但我认为您最好直接使用系统调用。
最后一件事,在&#34;自己做&#34;面前。您必须检查读写调用的返回值。它们可能读取/写入的字节数比您要求的少。
如果你可以管理一个循环缓冲区,你应该在函数返回短路时切换读/写...磁盘可能更准备好读取或写入所以没有必要浪费时间等待而不是切换到另一件事你必须这样做。
现在您可能想要探索的最后一件事 - 查看sendfile
系统调用。它的构建是为了通过在内核中执行所有副本来加速Web服务器并避免上下文切换和memcpys,但如果它与两个磁盘文件描述符一起使用,则可以在此处使用。