2016-12-03 3 views
0

Я хотел бы разобрать .xml.bzip2 Викимедиа свалках без извлечения всего файла или выполнения каких-либо XML проверки:Чтение очень большие файлы .xml.bz2

var filename = "enwiki-20160820-pages-articles.xml.bz2"; 

var settings = new XmlReaderSettings() 
{ 
    ValidationType = ValidationType.None, 
    ConformanceLevel = ConformanceLevel.Auto // Fragment ? 
}; 

using (var stream = File.Open(filename, FileMode.Open)) 
using (var bz2 = new BZip2InputStream(stream)) 
using (var xml = XmlTextReader.Create(bz2, settings)) 
{ 
    xml.ReadToFollowing("page"); 
    // ... 
} 

В BZip2InputStream работает - если я использую StreamReader , Я могу читать XML по строкам. Но когда я использую XmlTextReader, он терпит неудачу при попытке выполнить чтение:

System.Xml.XmlException: «Неожиданный конец файла произошла. Следующие элементы не закрыты: mediawiki. Строка 58, позиция 1. '

Поток bzip: не на EOF. Возможно ли открыть XmlTextReader поверх потока BZip2? Или есть другие способы сделать это?

+0

Файлы zip-файлов (gz) и gz содержат одну статью. Если gz содержит несколько файлов, вы можете прочитать индекс и извлечь один файл. Поскольку gz содержит один файл, вам необходимо загрузить весь файл и извлечь его, прежде чем вы сможете анализировать данные xml. – jdweng

+1

«Очень большой» не имеет смысла: он может означать что угодно: от 1 Мб до 1 Тб. Если вы не можете дать нам номер, не беспокойтесь упоминать размер. –

+0

@jdweng - этот дамп - это один, очень большой XML-файл, содержащий всю Википедию, а не архив отдельных файлов. – user655321

ответ

0

Это должно сработать. Я использовал комбинацию XmlReader и Xml Linq. Вы можете проанализировать документ XElement по мере необходимости.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml; 
using System.Xml.Linq; 


namespace ConsoleApplication29 
{ 
    class Program 
    { 
     const string URL = @"https://dumps.wikimedia.org/enwiki/20160820/enwiki-20160820-abstract26.xml"; 
     static void Main(string[] args) 
     { 
      XmlReader reader = XmlReader.Create(URL); 

      while (!reader.EOF) 
      { 
       if (reader.Name != "doc") 
       { 
        reader.ReadToFollowing("doc"); 
       } 
       if (!reader.EOF) 
       { 
        XElement doc = (XElement)XElement.ReadFrom(reader); 
       } 
      } 

     } 
    } 
} 
+0

Спасибо, хотя это все еще использует входной XML-файл, а не сжатый XML. Я могу использовать в основном этот код в своем локальном файле при распаковке, но упаковка BZip2InputStream с XmlReader по-прежнему вызывает одно и то же исключение. – user655321

+0

Когда я загрузил файл раньше, я не смог прочитать файл непосредственно на хроме. Мне пришлось сохранять файл на диск. Мне интересно, если вы загрузили файл на диск перед открытием, если вы получите такую ​​же ошибку. Я не пробовал мой код читать весь файл из URL. Хотите знать, произошла ли такая же ошибка. – jdweng

Смежные вопросы