提问人:Pawcio 提问时间:11/17/2023 更新时间:11/17/2023 访问量:17
ZipArchiveEntry.ExtractToFile() 适用于“winrar.zip”,但不适用于“msbuild.zip”
ZipArchiveEntry.ExtractToFile() works with "winrar.zip" but not "msbuild.zip"
问:
所以我使用以下方法来提取档案。
public static void extractArchive(string zipFile, string destination) {
destination = Path.GetFullPath(destination);
if (!destination.EndsWith(Path.DirectorySeparatorChar.ToString()))
destination += Path.DirectorySeparatorChar;
using (var arc = ZipFile.OpenRead(zipFile)) {
foreach (var e in arc.Entries) {
var des = Path.GetFullPath(
Path.Combine(destination + e.FullName));
if (des.EndsWith(Path.DirectorySeparatorChar.ToString())) {
if (!Directory.Exists(des)) Directory.CreateDirectory(des);
continue;
}
if (File.Exists(des) || !des.StartsWith(destination)) continue;
Console.WriteLine($@"extracting ""{e}"" to ""{des}""");
e.ExtractToFile(des);
}
}
}
当我使用 WinRAR 提取手动打包的存档时,它可以正常工作,但是当使用 MS Build 任务打包存档时,它会引发异常:
<Target Name="AfterBuild">
<Message Text="Second occurrence" />
<ZipDirectory Overwrite="true" SourceDirectory="$(TargetDir)\archive\" DestinationFile="$(TargetDir)\VS_MSBS_task.zip" />
</Target>
static void Main(string[] args) {
var dest = Directory.GetCurrentDirectory();
dest = Path.Combine(dest, "output");
zip("Winrar zip", "Winrar.zip", dest);
zip("VisualStudio zip", "VS_MSBS_task.zip", dest); //exception
Console.WriteLine("Done");
Console.ReadKey();
}
private static void zip(string name, string zipFile, string dest) {
Console.WriteLine($"-----------------{name}--------------------------------------------------------");
if(Directory.Exists(dest))
Directory.Delete(dest, true);
Directory.CreateDirectory(dest);
try {
extractArchive(zipFile, dest);
}catch (Exception ex) {
Console.WriteLine(ex);
}
Console.WriteLine($"-----------------FINISHED------------------------------------------------------");
}
有了“VS_MSBS_task.zip”,我得到:
System.IO.DirectoryNotFoundException:“找不到路径”path\to\file\in\subfolder.extension“的一部分。
//ZipFileExtensions.cs:
public static void ExtractToFile(this ZipArchiveEntry source, string destinationFileName, bool overwrite)
{
//...
using (Stream destination = File.Open(destinationFileName, mode, FileAccess.Write, FileShare.None))
{
//..
}
//..
}
在这两种情况下,该方法的输入看起来完全相同,所以我想这是一个错误,或者我遗漏了什么?System.IO.Compression
下面是控制台输出:
-----------------Winrar zip--------------------------------------------------------
extracting "sub1/fileInSubFolder.cs" to "C:\...\ZipExtractTest\bin\Debug\output\sub1\fileInSubFolder.cs"
extracting "text.txt" to "C:\...\ZipExtractTest\bin\Debug\output\text.txt"
-----------------FINISHED------------------------------------------------------
-----------------VisualStudio zip--------------------------------------------------------
extracting "text.txt" to "C:\...\ZipExtractTest\bin\Debug\output\text.txt"
extracting "sub1/fileInSubFolder.cs" to "C:\...\ZipExtractTest\bin\Debug\output\sub1\fileInSubFolder.cs"
System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\...\ZipExtractTest\bin\Debug\output\sub1\fileInSubFolder.cs'.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
at System.IO.Compression.ZipFileExtensions.ExtractToFile(ZipArchiveEntry source, String destinationFileName, Boolean overwrite)
at System.IO.Compression.ZipFileExtensions.ExtractToFile(ZipArchiveEntry source, String destinationFileName)
at ZipExtractTest.Program.extractArchive(String zipFile, String destination) in C:\...\ZipExtractTest\Program.cs:line 48
at ZipExtractTest.Program.zip(String name, String zipFile, String dest) in C:\...\ZipExtractTest\Program.cs:line 26
-----------------FINISHED------------------------------------------------------
Done
答:
0赞
Pawcio
12/20/2023
#1
问题是 msbuild.zip 不包含目录条目。 通过确保父目录存在来修复此问题:
//...
if (File.Exists(des) || !des.StartsWith(destination)) continue;
var dir = Path.GetDirectoryName(des);
Directory.CreateDirectory(dir);
Console.WriteLine($@"extracting ""{e}"" to ""{des}""");
e.ExtractToFile(des);
评论
IOException
destinationFileName
zip()
"VS_MSBS_task.zip"
zip()
zip()
extractArchive()
if (des.EndsWith(Path.DirectorySeparatorChar.ToString()))...
VS_MSBS_task.zip
Winrar.zip
Winrar.zip
VS_MSBS_task.zip
if (!Directory.Exists(des)) Directory.CreateDirectory(des);
if (!Directory.Exists(des)) { Console.WriteLine($@"creating directory ""{des}"""); Directory.CreateDirectory(des); }