2015-11-17 4 views
2

Я пытаюсь разархивировать zip-файл, который находится внутри другого почтового индекса. Когда я пытаюсь получить FileStream второго zip, это дает мне ошибку. Как я мог просматривать контент? Это мой код:Распакуйте zip-файл, который находится внутри другого почтового индекса, с SharpZipLib

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 не является файлом на диске. Это всего лишь файл внутри zip-архива, как и файлы xml. Для этого вы должны GetInputStream(), как и для xml-файлов, Stream zipStream = zipArchive.GetInputStream (elementInsideZip); Затем вы можете снова вернуть метод для извлечения этого почтового индекса.

Вам нужно сначала извлечь файл почтового индекса, а затем следует рекурсивный вызов той же функции (Потому что почтовый файл может также содержать файл почтового индекса):

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-файл (File) не предоставляет вам поток произвольного доступа, но с последовательным потоком - вот как работают алгоритмы, такие как Deflate.

Чтобы загрузить zip-файл в zip-файле, вам нужно сначала сохранить внутренний почтовый файл. Для этого вы можете использовать временный файл или простой MemoryStream (если он не слишком большой). Это в основном обеспечивает вам требование произвольного доступа, тем самым решая проблему.