【发布时间】:2014-08-10 12:35:03
【问题描述】:
我有一个大的 xml 文件(要解析的 osm 映射数据文件)。要处理的初始代码是这样的:
FILE* file = fopen(fileName.c_str(), "r");
size_t BUF_SIZE = 10 * 1024 * 1024;
char* buf = new char[BUF_SIZE];
string contents;
while (!feof(file))
{
int ret = fread(buf, BUF_SIZE, 1, file);
assert(ret != -1);
contents.append(buf);
}
size_t pos = 0;
while (true)
{
pos = contents.find('<', pos);
if (pos == string::npos) break;
// Case: found new node.
if (contents.substr(pos, 5) == "<node")
{
do something;
}
// Case: found new way.
else if (contents.substr(pos, 4) == "<way")
{
do something;
}
}
然后这里人们告诉我应该使用内存映射文件来处理那些“大数据文件”, 详情在这里: how to read to huge file into buffer,
我的意思是当它是固定大小并且不是很大时,我可以加载一次到内存中并将内容附加到字符串对象,然后我可以应用 find()、方法和其他字符串方法来提取节点xml 文件的内容。 (我的问题开头的代码使用这种方法,我测试会产生正确的结果)。那么如果文件很大,如何应用那些方法(不使用libxml之类的xml库)?
总之,对于小型 xml 文件,我可以将整个内容加载到 std::string 并应用 find()、substr() 操作并在 xml 文件中获得想要的信息。当xml文件很大时,需要使用内存映射文件来处理。然后可以将整个内容附加到 std::string,我如何不使用 exsit xml 库来解析文件?
希望我已经清楚地表达了我的问题。
【问题讨论】:
-
我不确定我是否理解您的问题。无论您分配缓冲区(应该使用vector
,而不是new char [],btw)还是内存映射,文件都与解析该文件完全无关。还是我缺少连接?无论如何,XML 的结构绝不是基于行的,所以如果您在解析 XML 时考虑行,那么您已经走错了路。对于大文件,我会使用专用的 XML 解析器,可能是带有 SAX 接口的解析器。 -
你在上一个问题上选择了错误的答案。
-
你听说过SAX parsers 吗?引用文章:因此,SAX 解析器所需的最小内存与 XML 文件的最大深度成正比 [...]
-
我并不是说我逐行读取 xml 文件。我的意思是当它是固定大小并且不是很大时,我可以将一次加载到内存中并将内容附加到字符串对象,然后我可以应用 find()、方法和其他字符串方法来提取节点内容xml 文件。那么如果文件很大,如何应用那些方法(不使用libxml之类的xml库)?
-
我确定我不明白这个问题。