加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – ofstream :: operator <<(streambuf)是一种复制文件

发布时间:2020-12-16 10:20:01 所属栏目:百科 来源:网络整理
导读:我需要一个跨平台,没有外部库,复制文件的方式.在我的第一次传递中我提出了(错误处理省略): char buffer[LEN];ifstream src(srcFile,ios::in | ios::binary);ofstream dest(destFile,ios::out | ios::binary);while (!src.eof()) { src.read(buffer,LEN); de
我需要一个跨平台,没有外部库,复制文件的方式.在我的第一次传递中我提出了(错误处理省略):

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上使用运算符<<(streambuf)效率低下. .read()/.write()循环看起来总是比运算符<<更好. 此外,在上面的代码中更改缓冲区的大小不会影响对硬盘驱动器的读写大小.为此,您需要使用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();

}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读