我有一个大的维基百科转储,我想切成不同的文件(每篇文章1个文件)。我写了一个VB应用程序来为我做这个,但它很慢,并在切割几个小时后被废弃。我目前正在使用另一个应用程序将文件拆分为较小的50mb块,但这需要很长时间(每个块需要20-30分钟)。如果我这样做,我应该能够单独削减每一个。
有没有人建议更快地删除此文件?
答案 0 :(得分:3)
使用C#执行此操作的最简单方法是使用XmlReader。您可以单独使用XmlReader来实现最快的实现,或者与新的LINQ XNode类结合使用,以获得性能和易用性的完美结合。有关示例,请参阅此MSDN文章:http://msdn.microsoft.com/en-us/library/system.xml.linq.xnode.readfrom.aspx。
您应该能够修改示例,以便一次仅在内存中保存一个文档的节点,然后将其作为文件写回。它应该运行良好,适用于非常大的文件。
答案 1 :(得分:0)
我假设你正在使用DOM解析器。对于可能较大的文件,您应始终使用SAX解析器。 DOM解析器将整个文件读入内存,SAX解析器一次尽可能少地读取,因此运行效率更高。 This tutorial描述了如何编写C#SAX解析器,VB应该非常相似。
答案 2 :(得分:0)
如果我在Java中这样做,我会使用javax.xml.stream.XMLEventReader和javax.xml.stream.XMLEventWriter。
在某种伪代码中,我们假设<article>
标记分隔每个维基百科文章,您不需要担心嵌套的<article>
标记,并且您有一个openNewWriter()
函数打开一个新的XMLEventWriter
,写入一篇具有本文合适名称的新文件。
然后我的代码看起来像这样:
XMLEventReader r = // an XMLEventReader for the original wikipedia dump
XMLEventWriter w = null;
bool isInsideArticle = false;
while (r.hasNext()){
XMLEvent e = r.nextEvent();
if (e.isStartElement() &&
e.asStartElement().getName().getLocalPart().equals("article")){
w = openNewWriter();
// write the stuff that belongs outside the <article> tag
// by synthesizing XMLEvents and using w.add() to add them
w.add(e);
isInsideArticle = true;
} else if (e.isEndElement() &&
e.asEndElement().getName().getLocalPart().equals("article")) {
w.add(e);
// write the stuff that belongs outside the <article> tag
// by synthesizing XMLEvents and using w.add() to add them
isInsideArticle = false;
w.close();
} else if (isInsideArticle) {
w.add(e);
} else {
// this tag gets dropped on the floor because it's not inside any article
}
}
现在您需要做的就是在.NET中找到流式XML类。我认为它们是system.xml.XMLReader和system.xml.XMLWriter,但我的专业知识不在.NET中,我无法从文档中看出它们是否与Java版本完全相同给了你。
(我的目的是向您展示如何处理问题,而不是告诉您所需类的名称。)
答案 3 :(得分:-1)
你应该试试vtd-xml,我们让人们告诉我们拆分大型XML文件的效果如何...... http://www.codeproject.com/KB/XML/xml_processing_future.aspx 我们也被告知DOM需要永远