gpt4 book ai didi

c++ - ofstream::operator<<(streambuf) 是一种复制文件的缓慢方法

转载 作者:太空狗 更新时间:2023-10-29 19:46:48 34 4
gpt4 key购买 nike

我需要一种跨平台、无需外部库的文件复制方式。在我的第一遍中,我想出了(省略了错误处理):

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<<(streambuf) 的实现每次移动 1 个字符(使用 snetxc()/sputc())。

有没有办法让这个方法更快?我原来的方法有缺点吗?

更新:在 Windows 上使用 operator<<(streambuf) 效率低下。 .read()/.write() 循环看起来总是比 operator<< 表现得更好。

另外,在上面的代码中改变缓冲区的大小不会影响硬盘读写的大小。为此,您需要使用 stream.rdbuf()->pubsetbuf() 设置缓冲区。

最佳答案

我想知道您的 fstream 是否默认是无缓冲的。 GCC 4.5.2 默认使用内部缓冲区,但我认为标准没有要求。您是否尝试过使用 pubsetbuf(见下文)为您的输入/输出流设置缓冲区。

在我的系统上进行快速测试,如果我将 LEN 设置为 0(因此无缓冲),复制一个 1 MB 的文件需要 10 秒。使用 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();

}

关于c++ - ofstream::operator<<(streambuf) 是一种复制文件的缓慢方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7250720/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com