案例:存在需要由.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