使用 SharpZipLib 解压缩另一个 zip 中的 zip 文件
Unzip a zip file that is inside another zip with SharpZipLib
我正在尝试解压缩另一个 zip 文件中的 zip 文件。当我尝试获取第二个 zip 的 FileStream
时,它给我一个错误。我如何查看内容?
这是我的代码:
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 来读取 headers、文件 table、目录 table 等。压缩的 ZIP(文件)流不需要它不会为您提供随机访问流,而是提供顺序流——这正是 Deflate 等算法的工作方式。
要加载压缩文件中的压缩文件,您需要先将内部压缩文件存储在某个地方。为此,您可以使用临时文件或简单的 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);
}
我正在尝试解压缩另一个 zip 文件中的 zip 文件。当我尝试获取第二个 zip 的 FileStream
时,它给我一个错误。我如何查看内容?
这是我的代码:
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 来读取 headers、文件 table、目录 table 等。压缩的 ZIP(文件)流不需要它不会为您提供随机访问流,而是提供顺序流——这正是 Deflate 等算法的工作方式。
要加载压缩文件中的压缩文件,您需要先将内部压缩文件存储在某个地方。为此,您可以使用临时文件或简单的 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);
}