我正在序列化多个对象,并希望将给定的字符串保存到文件中。结构如下:
一些字符串和长属性,然后是可变数量的maps<long, map<string, variant> >
。我的第一个想法是创建一个有效的JSONFile但这很难做到(所有的地图都很大,我的临时内存不够大)。由于我无法将所有内容序列化,因此我必须逐个进行。我打算这样做,然后我想将收到的字符串保存到文件中。这是它的样子:
{ "Name": "StackOverflow"}
{"map1": //map here}
{"map2": //map here}
正如您所看到的,这不是一个有效的JSON对象,而是一个文件中的3个有效JSONObject。现在我想反序列化,我需要给反序列化器提供一个有效的JSONObject。每当我将新的JSONObject写入文件时,我就已经保存tellp()
,所以在这个例子中我将保存以下地址:26,endofmap1,endofmap2。
这是我想要做的:我想使用这些地址,从我写的文件中提取字符串。我需要一个从0到(26-1)的字符串,一个从26到(endofmap1-1)的字符串和一个从endofmap1到(endofmap2-1)的字符串。由于这些字符串是有效的JSONObjects,我可以毫无问题地反序列化它们。
我该怎么做?
答案 0 :(得分:1)
我会创建一个serialize
和deserialize
类,您可以将其用作层次结构的一部分。
例如,在粗略的C ++伪代码中:
class Object : public serialize, deserialize {
public:
int a;
float b;
Compound c;
bool serialize(fstream& fs) {
fs << a;
fs << b;
c->serialize(fs);
fs->flush();
}
// same for deserialize
};
class Compound : serialize, deserialize {
public:
map<> things;
bool serialize(fstream& fs) {
for(thing : things) {
fs << thing;
}
fs->flush();
}
};
有了这个,你可以使用JSON,因为文件将被写为你的行走。
<强>更新强>
要从文件中提取特定字符串,您可以使用以下内容:
// pass in an open stream (streams are good for unit testing!)
std::string extractString(fstream& fs) {
int location = /* the location of the start from file */;
int length = /* length of the string you want to extract */;
std::string str;
str.resize(length);
char* begin = *str.begin();
fs->seekp(location);
fs->read(begin, length);
return str;
}
答案 1 :(得分:0)
基于你说&#34;我的临时记忆力不够大&#34;,我将假设两种可能性(虽然某种代码示例可以帮助我们帮助你!)。
可能性一,文件太大
你在这里遇到的问题不是一个新问题 - 一个对内存来说太大的文件,假设你的算法没有缓冲所有数据,你的堆栈当然可以处理递归。
在Windows上,您可以使用MapViewOfFile function,MSDN has plenty of detail on that。这个功能将有效地抓住一个&#34;视图&#34;文件的一部分 - 允许您加载足够的文件以仅修改所需内容,然后在以后的偏移处关闭和打开视图。
如果您使用的是其他平台,则会有类似的功能。
可能性二,你一下子做得太多了 另一种选择更多的是软件工程&#34;问题。你有很多数据,当你把它们放在你的std :: maps中时,就会耗尽堆内存。
如果是这种情况,你需要使用一些聪明的想法 - 这里有一些想法!
这对于需要排序或关联的数据非常有效。