用.NET读取压缩的xml

时间:2010-01-11 09:19:33

标签: .net xml zip

案例:有一个大的压缩xml文件,需要由.NET程序解析。主要问题是文件太大,因此无法完全加载到内存中并解压缩。

需要逐个阅读文件,以解压缩这些部分后它们是“一致的”。如果一个部分只包含一个节点的一半,则无法在任何xml结构中进行解析。

我们将不胜感激。 :)

编辑:当前解决方案逐个部分地提取整个zip文件,并将其作为xml文件写入磁盘。然后读取并解析xml。到目前为止,我的网站没有更好的想法:)。

5 个答案:

答案 0 :(得分: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()) 
            {
                ....
            }
        }
    }
}

答案 1 :(得分:1)

你没有尝试过DotNetZip Library (click on this link)吗?

回复您最近的版本::
你所做的是标准 流量/方式..根据我的知识 没有替代品。

答案 2 :(得分:1)

您可以尝试SharpZipLib,然后使用XmlReader开始解析它。

答案 3 :(得分:0)

关于你的编辑:除非你实际上希望将该xml文件放在磁盘上(当然在某些情况下可能是这种情况),我会将其提取到MemoryStream而不是

答案 4 :(得分:0)

嗯,这里有两个问题,解压缩文件的方式可以为您提供数据块,以及一种能够一次只读取数据块就能读取XML的方法。这与我们大多数人习惯于处理XML的方式不同,我们只是将它一次性读入内存,但你说这不是一种选择。

这意味着您将不得不使用仅针对此案例构建的Streams。此解决方案可以使用,但可能会受到限制,具体取决于您希望对XML数据执行的操作。你说它需要被解析,但你能够做到这一点的唯一方法(因为你不能把它保存在内存中)是能够以“消防软管方式”读取它,因为它解析了每个节点。 Hopefull足以能够提取您需要的数据或处理它,但是您也需要(将其戳入数据库,仅提取您所关注的部分并将其保存到较小的内存XML文档中等等)

所以第一份工作,从你的zip文件中获取一个流,很容易用SharpZipLib(+1到鲁本斯)。在项目中添加对SharpZipLib dll的引用。下面是一些从zip创建流的代码,然后将其添加到内存流中(您可能不想这样做,但它会告诉您如何使用它来获取数据的byte [],您只需要流):

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;
        }

然后,如果你遵循这篇文章:来自MS的http://support.microsoft.com/kb/301228你应该能够合并两批代码并开始从zip流中读取你的XML:)