[英]How to save stl container in disk?
我有一個 stl 容器,可以保存大量數據。
例如,定義是:
std::unordered_map<std::string, std::vector<int32_t> > m; // there are 10 million data in this container
我想要的是將它保存在一個文件中,然后下一次,我可以讀取這個文件以快速恢復它。
我認為正常的方式,如:
write(&m, sizeof(m))
不起作用,因為它只保存指針。
那么,我怎樣才能將它保存在文件中並通過讀取文件來恢復它?
選擇一種文件格式,例如一個簡單的列表,遍歷您的容器並寫入每個元素:
for (const auto &el : m) {
file << el.first << '\n' << el.second.size() << '\n';
for (const auto &vecEl : el.second) {
file << vecEl << '\n';
}
}
然后你可以讀取文件
std::string first;
std::size_t count;
while (std::getline(file, first) && file >> count) {
std::vector<int32_t> v(count);
for (auto &vecEl : v) {
file >> vecEl;
}
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
m[first] = v;
}
這只是一個草圖。 您可能必須添加錯誤檢查。
鑒於您不熱衷於使用 boost,最低努力最低可重用性選項類似於:
// some support macros for easy error detection/handling...
#define FATAL(MSG) \
do { \
std::cerr << "FATAL ERROR at line " << __LINE__ << ":\n" \
" " << MSG << '\n'; \
exit(EXIT_FAILURE); \
} while (false)
#define ASSERT(X, MSG) \
do { \
if (X) break; \
FATAL("ASSERT(" #X ") FAILED; " << MSG); \
} while (false)
// output your container to disk...
if (std::ofstream out{filename}) {
for (auto& [key, value] : m) {
out << key.size() << ' ';
out.write(key.data(), key.size();
out << ' ' << value.size();
for (auto& i : values)
out << ' ' << i;
out >> '\n';
}
ASSERT(out, "failed while writing to " << filename);
}
else
FATAL("failed to create " << filename);
這只會創建一個文件,其中包含以下行:
13 A 13 char str 5 1 2 3 4 5
前導 13 表示您在解析字符串之前就知道字符串中有多少個字符,這樣可以省去我們想出一些 escaping 和終止符約定的麻煩,或者沒有一個的風險(例如,假設字符串沒有嵌入換行符一般是有風險的)。 第一個“5”表示數組長度,只需要加快加載速度,因為它可以讓您預先預留足夠的 memory,這可能比使用.push_back
更快,並且在加載數組期間必須resize
。
讀取文件則變為:
if (std::ifstream in{filename}) {
size_t len;
while (in >> len) {
std::string key;
key.resize(len);
ASSERT(in.read(key.data(), len));
ASSERT(in >> len);
std::vector<int32_t> v;
v.reserve(len);
while (len--) {
ASSERT(in >> num);
v.push_back(num);
}
}
ASSERT(out.eof(), "failed to parse string size");
m[std::move(key)] = std::move(v);
}
else
FATAL("failed to open " << filename);
我還沒有測試過這個,所以根據需要使用/測試/調試....
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.