C# 使用SharpZipLib解压另一个zip中的zip文件

C# 使用SharpZipLib解压另一个zip中的zip文件,c#,filestream,sharpziplib,C#,Filestream,Sharpziplib,我正在尝试解压缩另一个zip文件中的zip文件。当我试图获取第二个zip文件的文件流时,它会给我一个错误。如何查看内容? 这是我的代码: try { FileStream fs = File.OpenRead(location); ZipFile zipArchive = new ZipFile(fs); foreach (ZipEntry elementInsideZip in zipArchive)

我正在尝试解压缩另一个zip文件中的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);
                }
            }
        }

我不确定这是否可行。让我解释一下:

读取ZIP文件需要随机访问文件IO来读取标题、文件表、目录表等。压缩的ZIP(文件)流不提供随机访问流,而是提供顺序流——这就是像Deflate这样的算法的工作方式


要在zip文件中加载zip文件,首先需要将内部zip文件存储在某个位置。为此,您可以使用临时文件或简单的
MemoryStream
(如果不太大)。这基本上为您提供了随机访问要求,从而解决了问题。

此时,zip存档名称不是磁盘上的文件。它只是zip存档中的一个文件,就像xml文件一样。您应该像对待xml文件一样获取GetInputStream(),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);
}