我需要处理内存中的大量数据(不使用文件/fstream(,我知道streambuf的VS实现不允许这样做,因为它使用32位计数器(https://github.com/microsoft/STL/issues/388)。我以为Boost可能会帮助我,但显然它处理得不好(或者我错过了什么(。
#include <vector>
#include <iostream>
#include <boost/iostreams/stream.hpp>
namespace bs = boost::iostreams;
int main()
{
uint64_t mb1 = 1024 * 1024;
uint64_t gb1 = 1024 * mb1;
uint64_t mbToCopy = 2048;
std::vector<char> iBuffer(mb1);
std::vector<char> oBuffer(4 * gb1);
bs::stream<bs::array_sink> oStr(oBuffer.data(), oBuffer.size());
for (int i = 0; i < mbToCopy; i++) {
oStr.write(iBuffer.data(), iBuffer.size());
}
std::cout << oStr.tellp() << std::endl; // (1)
oStr.seekp(0, std::ios_base::beg);
std::cout << oStr.tellp() << std::endl; // (2)
}
只要mbToCopy不大于2048并且输出为:,此代码就可以正常工作
2147483648
0
当我将mbToCopy更改为2049时,输出为:
2148532224
4294967296
正如您所看到的,当我试图移回流的开头时(这是示例用法,但我需要能够重新定位到流中的任何位置(,它会使我远远超出流的当前大小,流变得不可靠。更重要的是,当我将mbToCopy设置为2049并将oBuffer的大小减小到3GBoStr.seekp开始崩溃时。
你知道Boost是否提供了其他可以帮助我的解决方案吗?
我建议这里根本不要使用流。他们似乎引入了不必要的开销:
#include <cassert>
#include <iostream>
#include <vector>
static inline auto operator""_kb(unsigned long long v) { return v << 10ull; }
static inline auto operator""_mb(unsigned long long v) { return v << 20ull; }
static inline auto operator""_gb(unsigned long long v) { return v << 30ull; }
int main()
{
std::vector<char> iBuffer(1_mb);
std::vector<char> oBuffer(12_gb);
auto pos = oBuffer.begin();
for (size_t i = 0; i < 8192; i++) {
assert(std::next(pos, iBuffer.size()) <= oBuffer.end());
pos = std::copy_n(iBuffer.begin(), iBuffer.size(), pos);
}
auto tellp = [&] { return std::distance(oBuffer.begin(), pos); };
auto seekp = [&](size_t from_beg) { pos = std::next(oBuffer.begin(), from_beg); };
std::cout << tellp() << std::endl; // (1)
seekp(0);
std::cout << tellp() << std::endl; // (2)
}
在我的系统上打印,没有任何问题:
8589934592
0
当然,我引入tellp()
/seekp()
助手只是为了使代码尽可能相似。你也可以写:
auto const beg = oBuffer.begin();
auto pos = beg;
for (size_t i = 0; i < 8192; i++) {
assert(std::next(pos, iBuffer.size()) <= oBuffer.end());
pos = std::copy_n(iBuffer.begin(), iBuffer.size(), pos);
}
std::cout << (pos-beg) << std::endl; // (1)
pos = beg;
std::cout << (pos-beg) << std::endl; // (2)
输出完全相同。