案例:存在需要由.NET程序解析的大型压缩xml文件。主要问题是文件太大,因此无法在内存中完全加载并解压缩。使用.NET读取压缩的xml
该文件需要逐一阅读,以解压缩这些部分后,他们是“一致的”。如果一个零件只包含一个节点的一半,那么它将不可能在任何xml结构中被解析。
每一个帮助将不胜感激。 :)
编辑:当前的解决方案部分提取整个zip文件,并将其作为xml文件写入磁盘。然后读取并解析xml。到目前为止,从我的网站没有更好的想法:)。
案例:存在需要由.NET程序解析的大型压缩xml文件。主要问题是文件太大,因此无法在内存中完全加载并解压缩。使用.NET读取压缩的xml
该文件需要逐一阅读,以解压缩这些部分后,他们是“一致的”。如果一个零件只包含一个节点的一半,那么它将不可能在任何xml结构中被解析。
每一个帮助将不胜感激。 :)
编辑:当前的解决方案部分提取整个zip文件,并将其作为xml文件写入磁盘。然后读取并解析xml。到目前为止,从我的网站没有更好的想法:)。
使用DotNetZip你可以做你的阅读XML这个:
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 – 2010-01-11 16:12:46
你没有试过DotNetZip Library (click on this link)?
在回答你的最新版::
你在做什么是标准 流/方式..
按我的知识 有这个没有办法。
您可以尝试SharpZipLib
,然后使用XmlReader
开始解析它。
关于您的编辑:除非你真正想要向对磁盘xml文件(当然这可能是在某些情况下的情况下),我将它解压到一个MemoryStream代替。
嗯,你在这里有两个问题,解压缩文件的方式可以给你大量的数据和方法,以便能够读取基于一次只能读取块的XML。这与我们大多数人习惯于处理XML的方式不同,我们只是一次将它读入内存中,但您说这不是一种选择。
这意味着你将不得不使用为这种情况构建的Streams。此解决方案可以工作,但可能会受到限制,具体取决于您希望对XML数据执行的操作。你说它需要被解析,但是你能够做到这一点的唯一方式(因为你不能将它保存在内存中)应该能够以“消防水带方式”读取它,并在解析每个节点时逐步浏览。 Hopefull足够能够提取出你需要的数据或者处理它(不过你也需要它)(把它插入数据库,只提取你被嵌入的部分并将它们保存到一个更小的内存XML文件中?等等)
因此,第一份工作,从您的zip文件中获取流,使用SharpZipLib(+1到Rubens)很容易。在项目中添加对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。哪个是坏的时刻... – Alex 2010-01-11 12:42:39
嗯“定义大小”,你可以通过定义缓冲区大小来做到这一点?对于现在的问题,我感到困惑不解。据了解,你有一个巨大的XML文件,它不可能适合内存。此方法允许您一次处理整个文件块,但是您的代码可以将其视为一个巨大的XML文件,彻底解决它的所有问题,并执行每个节点都需要执行的操作。那不是你要做什么?如果不是,请提供更多关于您想要对XML或组成XML的详细信息。 – 2010-01-11 20:48:52
你也读过MS的文章吗? – 2010-01-11 20:52:11
我知道这个文件太大了,不能一次装入内存。这意味着什么“按部分解压缩”?你的意思是,作为一个流? – Cheeso 2010-01-11 15:55:33