gpt4 book ai didi

C++ 将 N 个字节从一个流复制到另一个流

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:44:35 25 4
gpt4 key购买 nike

给定 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;
}

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

最佳答案

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

您可以在此处查找示例实现: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<char> buff(fileSize, 0))并在一次调用中将其写入输出流。

因为你只想复制N bytes 那么你应该将该值与文件大小减去起始偏移量进行比较,以便仍然能够在一次大读/写中完成它。

例如:

// 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());
...
}

关于C++ 将 N 个字节从一个流复制到另一个流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41610926/

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