【问题标题】:C++ copy N bytes from one stream to anotherC ++将N个字节从一个流复制到另一个
【发布时间】:2017-05-27 10:15:30
【问题描述】:

假设ifstream 作为源,ofstream 作为目标,从源中的streampos(offset) 开始复制 N 个字节的最快方法是什么?

编辑

我想到的最简单的方法是使用简单的缓冲区:

char *buf = new char[N];
is.seekg(offset);
is.read(buf, N);
os.write(buf, N);
delete buf;

或更小的固定大小的缓冲区:

char buf[BUF_SIZE];
is.seekg(offset);
while (N > 0) {
    int n = min(BUF_SIZE, N);
    is.read(buf, n);
    os.write(buf, n);
    N -= n;
}

我想知道有什么比这更快或更高效。

【问题讨论】:

  • 请提供您目前尝试过的解决方案?并解释为什么没有工作。
  • 最快的方法取决于很多细节。您应该尝试几种不同的方法并对您感兴趣的系统进行基准测试。
  • @KamilKoczurek 在这种情况下,InputIterator firstOutputIterator result 是什么?
  • std::istream_iterator(in) 和 std::ostream_iterator(out)。
  • 注意应该是delete [] buf,在栈上分配缓冲区的buf可能会更快...

标签: c++ io fstream


【解决方案1】:

您可以尝试不同的解决方案。关于效率最重要的事情 - 衡量

您可以在此处查找示例实现:How to read a file into a vector elegantly and efficiently?

在大多数情况下,缓冲区越大,读/写的速度就越快。使用迭代器解决方案传递单个字节,例如:

std::copy(std::istream_iterator<char>(is),
          std::istream_iterator<char>(),
          std::ostream_iterator<char>(os));

虽然看起来不错,但在效率方面几乎是最糟糕的情况 - 至少对于我测试过的设置而言。

从指定的偏移量一次读取整个文件到一个大缓冲区可以获得最佳的时间结果——除非你有一些内存限制,否则你可以试试这个。为此,您应该计算文件大小,将数据读取到缓冲区(例如像这样初始化:std::vector&lt;char&gt; buff(fileSize, 0)),然后一次调用将其写入输出流。

由于您只想复制 N 字节,因此您应该将该值与文件大小减去起始偏移量进行比较,以便仍然能够进行一次大的读取/写入。

例如:

// helper function
streampos getSizeToEnd(ifstream& is)
{
    auto currentPosition = is.tellg();
    is.seekg(0, is.end);
    auto length = is.tellg() - currentPosition;
    is.seekg(currentPosition, is.beg);
    return length;
}

int main()
{
    std::ifstream is;
    std::ofstream os;
    ...
    const auto offset = 100;
    is.seekg(offset);
    std::vector<char> buff(getSizeToEnd(is), 0);

    // read the data chunk to buffer and from buffer to output stream
    is.read(buff.data(), buff.size());
    os.write(buff.data(), buff.size());
    ...
}

【讨论】:

    猜你喜欢
    • 2017-10-13
    • 2022-01-12
    • 2023-04-09
    • 1970-01-01
    • 2017-05-15
    • 2011-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多