我需要一种跨平台,没有外部库的复制文件的方式。在我的第一遍中,我想到了(省略了错误处理):
char buffer[LEN];
ifstream src(srcFile, ios::in | ios::binary);
ofstream dest(destFile, ios::out | ios::binary);
while (!src.eof()) {
src.read(buffer, LEN);
dest.write(buffer, src.gcount());
}
这很好,我完全知道它在做什么。
然后我发现了关于stackoverflow的帖子(很抱歉,现在无法找到链接),该帖子说我可以将上述所有代码替换为:
dest << src.rdbuf();
它既好又紧凑,但隐藏了很多功能。事实证明,它真的很慢,因为ofstream::operator <
我有办法使这种方法更快吗?我的原始方法是否有缺点?
更新:在Windows上使用operator <
另外,在上面的代码中更改缓冲区的大小不会影响对硬盘驱动器的读写大小。为此,您需要使用stream.rdbuf()-> pubsetbuf()设置缓冲区。
最佳答案
我想知道您的fstream默认情况下是否没有缓冲。默认情况下,GCC 4.5.2使用内部缓冲区,但我认为标准并不要求这样做。您是否尝试过使用pubsetbuf(请参见下文)为输入/输出流设置缓冲区。
在我的系统上进行的快速测试,如果我将LEN设置为0(因此没有缓冲),则需要10秒钟来复制一个1 MB的文件。有了4k缓冲区,它可以在不到一秒钟的时间内完成。
#include <iostream>
#include <fstream>
int main() {
using namespace std;
const char* srcFile = "test.in";
const char* destFile = "test.out";
ifstream src;
ofstream dest;
const int LEN=8192;
char buffer_out[LEN];
char buffer_in[LEN];
if (LEN) {
src.rdbuf()->pubsetbuf(buffer_in, LEN );
dest.rdbuf()->pubsetbuf(buffer_out, LEN);
} else {
src.rdbuf()->pubsetbuf(NULL, 0 );
dest.rdbuf()->pubsetbuf(NULL, 0);
}
src.open(srcFile, ios::in | ios::binary);
dest.open(destFile, ios::out | ios::binary);
dest << src.rdbuf();
}