C ++使用start和endpoint读取文件的特定部分

时间:2016-02-09 08:50:19

标签: c++ serialization readfile

我正在序列化多个对象,并希望将给定的字符串保存到文件中。结构如下:

一些字符串和长属性,然后是可变数量的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,我可以毫无问题地反序列化它们。

我该怎么做?

2 个答案:

答案 0 :(得分:1)

我会创建一个serializedeserialize类,您可以将其用作层次结构的一部分。

例如,在粗略的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 functionMSDN has plenty of detail on that。这个功能将有效地抓住一个&#34;视图&#34;文件的一部分 - 允许您加载足够的文件以仅修改所需内容,然后在以后的偏移处关闭和打开视图。

如果您使用的是其他平台,则会有类似的功能。

可能性二,你一下子做得太多了 另一种选择更多的是软件工程&#34;问题。你有很多数据,当你把它们放在你的std :: maps中时,就会耗尽堆内存。

如果是这种情况,你需要使用一些聪明的想法 - 这里有一些想法!

  1. 不要将所有数据加载到地图中。无论数据来自何处,都要获取数据源的CRC,索引或文件名。将该信息存储在地图中,并保留实际的&#34;大字符串&#34;在硬盘上。 - 这样您就可以在需要时加载每个数据。
  2. 这对于需要排序或关联的数据非常有效。

    1. 在需要编写数据时处理或加载数据。如果您不需要对数据进行排序或关联,为什么要事先将其加载到地图中?只需加载每个&#34;大字符串&#34;按顺序排列数据,然后用ofstream将它们写入文件。