2015-11-17 235 views
2

我試圖解壓縮另一個zip內的zip文件。當我嘗試獲得第二個zip的FileStream時,它給我一個錯誤。我如何查看內容? 這是我的代碼:使用SharpZipLib解壓縮另一個zip內的zip文件

try 
     { 
      FileStream fs = File.OpenRead(location); 
      ZipFile zipArchive = new ZipFile(fs); 
      foreach (ZipEntry elementInsideZip in zipArchive) 
      { 
       String ZipArchiveName = elementInsideZip.Name; 
       if (ZipArchiveName.Equals("MyZMLFile.xml")) 
       { 
        // I NEED XML FILES 
        Stream zipStream = zipArchive.GetInputStream(elementInsideZip); 
        doc.Load(zipStream); 
        break; 
       } 
       // HERE!! I FOUND ZIP FILE 
       else if (ZipArchiveName.Contains(".zip")) 
       { 
        // I NEED XML FILES INSIDE THIS ZIP 
        string filePath2 = System.IO.Path.GetFullPath(ZipArchiveName); 
        ZipFile zipArchive2 = null; 
        FileStream fs2 = File.OpenRead(filePath2);// HERE I GET ERROR: Could not find a part of the path 
        zipArchive2 = new ZipFile(fs2); 
       } 
      } 
     } 

回答

2

此時,zip存檔名稱不是磁盤上的文件。它就像xml文件一樣只是zip壓縮文件內的一個文件。你應該爲GetInputStream()做這個,就像你爲xml文件所做的一樣,Stream zipStream = zipArchive.GetInputStream(elementInsideZip);然後,您可以遞歸該方法以再次提取此zip。

你需要先提取ZIP文件,然後應該遞歸調用相同的功能(因爲那zip文件還可以包含一個zip文件):

private static void ExtractAndLoadXml(string zipFilePath, XmlDocument doc) 
{ 
    using(FileStream fs = File.OpenRead(zipFilePath)) 
    { 
     ExtractAndLoadXml(fs, doc); 
    } 
} 

private static void ExtractAndLoadXml(Stream fs, XmlDocument doc) 
{ 
    ZipFile zipArchive = new ZipFile(fs); 
    foreach (ZipEntry elementInsideZip in zipArchive) 
    { 
     String ZipArchiveName = elementInsideZip.Name; 
     if (ZipArchiveName.Equals("MyZMLFile.xml")) 
     { 
      Stream zipStream = zipArchive.GetInputStream(elementInsideZip); 
      doc.Load(zipStream); 
      break; 
     } 
     else if (ZipArchiveName.Contains(".zip")) 
     { 
      Stream zipStream = zipArchive.GetInputStream(elementInsideZip); 
      string zipFileExtractPath = Path.GetTempFileName(); 
      FileStream extractedZipFile = File.OpenWrite(zipFileExtractPath); 
      zipStream.CopyTo(extractedZipFile); 
      extractedZipFile.Flush(); 
      extractedZipFile.Close(); 
      try 
      { 
       ExtractAndLoadXml(zipFileExtractPath, doc); 
      } 
      finally 
      { 
       File.Delete(zipFileExtractPath); 
      } 
     } 
    } 
} 

public static void Main(string[] args) 
{ 
    string location = null; 
    XmlDocument xmlDocument = new XmlDocument(); 
    ExtractAndLoadXml(location, xmlDocument); 
} 
1

我不確定這是否可能。讓我解釋一下:

讀取ZIP文件需要隨機訪問文件IO來讀取頭文件,文件表,目錄表等。壓縮ZIP(文件)流不會爲您提供隨機訪問流,但是有一個順序流 - 這就是像Deflate這樣的算法的工作方式。

要在zip文件中加載zip文件,您需要先將內部zip文件存儲在某處。爲此,您可以使用臨時文件或簡單的MemoryStream(如果它不太大)。基本上爲您提供隨機訪問要求,從而解決問題。