2011-11-21 116 views
6

我正在C#中工作,並且正在爲互聯網下載一個帶有一個XML文件的zip文件。我希望加載這個XML文件。這是我到目前爲止有:在C中解壓縮流#

byte[] data; 
WebClient webClient = new WebClient(); 
try { 
    data = webClient.DownloadData(downloadUrl); 
} 
catch (Exception ex) { 
    Console.WriteLine("Error in DownloadData (Ex:{0})", ex.Message); 
    throw; 
} 

if (data == null) { 
    Console.WriteLine("Bulk data is null"); 
    throw new Exception("Bulk data is null"); 
} 

//Create the stream 
MemoryStream stream = new MemoryStream(data); 
XmlDocument document = new XmlDocument(); 

//Gzip 
GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress); 

//Load report straight from the gzip stream 
try { 
    document.Load(gzipStream); 
} 
catch (Exception ex) { 
    Console.WriteLine("Error in Load (Ex:{0})", ex.Message); 
    throw; 
} 

document.Load我總是收到以下異常:
神奇的數字在gzip頭信息是不正確的。確保你傳入一個GZip流。

我在做什麼錯了?

+1

你下載一個'GZip'或'Zip'?兩者不一樣。 – Oded

+0

'zip!= gzip' - 見http://en.wikipedia.org/wiki/Gzip和http://en.wikipedia.org/wiki/ZIP_%28file_format%29 – Polynomial

+0

我想這是我的第一個錯誤。這是一個不是Gzip的zip文件。 –

回答

5

我正在使用SharpZipLib,它工作的很棒!

下面是一個封裝庫

public static void Compress(FileInfo sourceFile, string destinationFileName,string destinationTempFileName) 
     { 
      Crc32 crc = new Crc32(); 
      string zipFile = Path.Combine(sourceFile.Directory.FullName, destinationTempFileName); 
      zipFile = Path.ChangeExtension(zipFile, ZIP_EXTENSION); 

      using (FileStream fs = File.Create(zipFile)) 
      { 
       using (ZipOutputStream zOut = new ZipOutputStream(fs)) 
       { 
        zOut.SetLevel(9); 
        ZipEntry entry = new ZipEntry(ZipEntry.CleanName(destinationFileName)); 

        entry.DateTime = DateTime.Now; 
        entry.ZipFileIndex = 1; 
        entry.Size = sourceFile.Length; 

        using (FileStream sourceStream = sourceFile.OpenRead()) 
        { 
         crc.Reset(); 
         long len = sourceFile.Length; 
         byte[] buffer = new byte[bufferSize]; 
         while (len > 0) 
         { 
          int readSoFar = sourceStream.Read(buffer, 0, buffer.Length); 
          crc.Update(buffer, 0, readSoFar); 
          len -= readSoFar; 
         } 
         entry.Crc = crc.Value; 
         zOut.PutNextEntry(entry); 

         len = sourceStream.Length; 
         sourceStream.Seek(0, SeekOrigin.Begin); 
         while (len > 0) 
         { 
          int readSoFar = sourceStream.Read(buffer, 0, buffer.Length); 
          zOut.Write(buffer, 0, readSoFar); 
          len -= readSoFar; 
         } 
        } 
        zOut.Finish(); 
        zOut.Close(); 
       } 
       fs.Close(); 
      } 
     } 
1

GZipStream Class描述的功能:可以使用多種常用的壓縮工具進行解壓縮

寫入到文件以.gz的擴展名的壓縮GZipStream對象;然而,這個類本身並沒有從.zip文件

將文件添加或提取文件,因此,除非你控制的服務器端文件,我建議尋找特定的拉鍊針對性庫(SharpZipLib例如提供功能)。

2

正如其他人所說的GZip和Zip不一樣,所以你可能需要使用一個zip庫。我使用了一個名爲庫:DotNetZip - 可從以下網站:

http://dotnetzip.codeplex.com/

4

顯然SharpZipLib是現在無人維護,你可能想避免它: https://stackoverflow.com/a/593030

在.NET 4.5現在有built in support for zip files ,所以你的例子那就是:

var data = new WebClient().DownloadData(downloadUrl); 

//Create the stream 
var stream = new MemoryStream(data); 

var document = new XmlDocument(); 

//zip 
var zipArchive = new ZipArchive(stream); 

//Load report straight from the zip stream 
document.Load(zipArchive.Entries[0].Open()); 
3

如果您有一個包含一個zip壓縮包有一個文件的字節數組,你可以使用ZipArchive類來獲得一個解壓縮的字節數組與文件的數據。 ZipArchive包含在.NET 4.5中,程序集System.IO.Compression.FileSystem中(您需要明確引用它)。

下面的函數,改編自this answer,工作對我來說:

public static byte[] UnzipSingleEntry(byte[] zipped) 
{ 
    using (var memoryStream = new MemoryStream(zipped)) 
    { 
     using (var archive = new ZipArchive(memoryStream)) 
     { 
      foreach (ZipArchiveEntry entry in archive.Entries) 
      { 
       using (var entryStream = entry.Open()) 
       { 
        using (var reader = new BinaryReader(entryStream)) 
        { 
         return reader.ReadBytes((int)entry.Length); 
        } 
       } 
      } 
     } 
    } 
    return null; // To quiet my compiler 
}