2015-11-17 184 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(如果它不太大)。基本上为您提供随机访问要求,从而解决问题。