2010-01-11 7 views
2

Случай: есть большой zipped-файл xml, который нужно проанализировать с помощью .NET-программы. Основная проблема - слишком большой размер файла, поэтому он не может быть полностью загружен в память и распакован.Прочитайте zipped xml с .NET

Файл должен быть прочитан частично по частям таким образом, чтобы после распаковки этих частей они были «согласованными». Если часть включает только половину узла, то в любой структуре xml невозможно разобрать.

Любая помощь будет оценена по достоинству. :)

Редактировать: текущее решение извлекает всю часть zip-файла по частям и записывает его как xml-файл на диск. Затем читает и анализирует xml. На моем сайте нет лучших идей :).

+2

Я понимаю, что файл слишком велик, чтобы вписаться в память за один раз. Что значит «распаковать по частям»? Вы имеете в виду, как поток? – Cheeso

ответ

4

Использование DotNetZip вы можете сделать это:

using (var zip = ZipFile.Read("c:\\data\\zipfile.zip")) 
{ 
    using (Stream s = zip["NameOfXmlFile.xml"].OpenReader()) 
    { 
     // Create the XmlReader object. 
     using (XmlReader reader = XmlReader.Create(s)) 
     { 
      while (reader.Read()) 
      { 
       .... 
      } 
     } 
    } 
} 
+0

приемлемый ответ. Это то, о чем я упоминал .. +1 –

1

Вы не попробовали DotNetZip Library (click on this link)?

В ответ на Ваше последнее издание ::
Что вы делаете, это стандартный поток /способ ..
По моим сведениям нет альтернативы для этого.

1

Вы можете отправить SharpZipLib, а затем использовать XmlReader, чтобы начать его разбор.

0

Что касается вашего редактирования: Если вы на самом деле хотите иметь файл XML на диске (который, конечно, может иметь место в некоторых сценариях), я бы извлечь его к MemoryStream вместо этого.

+0

В этом проблема - файл слишком большой для извлечения в память. Imaging действительно большой файл ... – Alex

+0

А, это большой: p Тогда, полагаю, нет. Если вы не можете приготовить какой-то способ просто потокового содержимого. Таким образом, вид расстегивания, чтения, использования, выброса в поток. Но я не знаю, можете ли вы сделать это с zip-файлами или нет ...? – Svish

+0

На самом деле это можно сделать с помощью zip-файлов, просто не знаю, сколько нужно читать за раз, чтобы иметь действительный xml. В другом случае алгоритм, который вы описали, разбивается на использование :). – Alex

0

Хммм у вас есть две проблемы, распаковывая файл таким образом, который может дать вам фрагменты данных и метод, позволяющий читать XML, основываясь на возможности читать только куски за раз. Это отличается от того, как большинство из нас используется для работы с XML, где мы просто читаем его за один раз в памяти, но вы говорите, что это не вариант.

Это означает, что вам придется использовать потоки, которые строятся именно для этого случая. Это решение будет работать, но оно может быть ограничено в зависимости от того, что вы надеетесь сделать с данными XML. Вы говорите, что его нужно разбирать, но единственный способ, которым вы сможете это сделать (поскольку вы не можете сохранить его в памяти), - это прочитать его в «способе пожарного шланга», проходящем через каждый узел по мере его синтаксического анализа , Hopefull достаточно для того, чтобы вытащить нужные вам данные или обработать их, но вам тоже нужно (вытолкнуть его в БД, извлечь только те разделы, в которые вы инсталлированы, и сохранить их в меньшем объеме в XML-документе XML и т. Д.).

Итак, первое задание, получите поток из вашего zip-файла, довольно легко сделать с SharpZipLib (+1 до Rubens). Добавьте ссылку на dll SharpZipLib в свой проект. Имеет некоторый код, который создает поток из zip, а затем добавляет его в поток памяти (вы можете не захотеть сделать этот бит, но он показывает вам, как я использую его для возврата байта [] данных, вам просто нужен поток):

using System; 
using System.IO; 
using ICSharpCode.SharpZipLib.Zip; 
using System.Diagnostics; 
using System.Xml; 

namespace Offroadcode.Compression 
{ 
    /// <summary> 
    /// Number of handy zip functions for compressing/decompressing zip data. 
    /// </summary> 
    public class Zip 
    { 

     /// <summary> 
     /// Decompresses a btye array of previously compress data from the Compress method or any Zip program for that matter. 
     /// </summary> 
     /// <param name="bytes">Compress data as a byte array</param> 
     /// <returns>byte array of uncompress data</returns> 
     public static byte[] Decompress(byte[] bytes) 
     { 
      Debug.Write("Decompressing byte array of size: " + bytes.Length ); 

      using(ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream stream = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream(new MemoryStream(bytes))) 
      { 
           // Left this bit in to show you how I can read from the "stream" and save the data to another stream "mem" 
       using (MemoryStream mem = new MemoryStream()) 
       { 
        int size = 0; 
        while(true) 
        { 
         byte[] buffer = new byte[4096]; 
         size = stream.Read(buffer, 0, buffer.Length); 

         if (size > 0) 
         { 
          mem.Write(buffer, 0, size); 
         } 
         else 
         { 
          break; 
         } 
        } 

        bytes = mem.ToArray(); 
       } 
      } 

      Debug.Write("Complete, decompressed size: " + bytes.Length); 

      return bytes; 
     } 

Затем, если вы будете следовать этой статье: http://support.microsoft.com/kb/301228 от MS, вы должны быть в состоянии объединить два лота кода и начать читать ваш XML из почтового потока :)

+0

Да, этот код позволяет нам распаковывать файл в памяти на разделенных частях , но по-прежнему не помогает определить размер этих частей. В лучшем случае каждая часть является допустимым xml. Какой плохой момент ... – Alex

+0

Хмм «определить размер», вы можете это сделать, указав размер буфера? Я довольно смущен, что сейчас проблема. Как понятно, у вас есть один огромный XML-файл, который невозможно поместить в память. Этот метод позволяет обрабатывать весь файл кусок в то время, но ваш код может рассматривать его как один огромный файл XML, греметь свой путь через все это и делать все, что нужно делать, как это происходит через каждый узел. Разве это не то, что вам делать? Если нет, предоставьте более подробную информацию о том, что вы хотите сделать с XML или составом XML. –

+0

Также вы прочитали статью от MS? –

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