我正在使用System.IO.Compression提取某些Zip文件的内容。问题是,只要有一个文件名包含某些Windows非法字符的条目,就会引发异常。我已经尝试了几件事,但是仍然找不到任何方法可以忽略不良条目并提取出好的条目。请考虑修改zip文件的内容对于我们正在执行的处理类型是不可能的,因此我必须按原样处理该文件。
系统通常会处理带有多个条目的文件,此数字是可变的,但是一个zip文件中最多可以包含300个条目,并且偶尔会有一个文件名,例如'myfile<name>.txt'
,其中包含尖括号, Windows显然是非法字符。我真的想忽略此条目,并继续提取ZipArchive中的其余条目。但这似乎是不可能的。
关于如何忽略ZipArchive不良条目的任何想法?
到目前为止,我已经尝试了不同的方法来分别获取条目,但是我总是得到完全相同的异常错误。
到目前为止,我尝试过一些事情:
采用常规方式遍历条目:
foreach (ZipArchiveEntry entry in ZipArchive.Entries)
试图按索引获取一个条目(即使第一个条目是有效的,这里也有例外):
ZipArchiveEntry entry = ZipArchive.Entries[0]
应用使用lambda表达式的过滤器来忽略无效条目(也是相同的例外):
var entries = zipArchive.Entries.Where(a =>
a.FullName.IndexOfAny(Path.GetInvalidFileNameChars() ) == -1);
这无济于事,我每次都遇到的异常如下:
在System.IO.Path.CheckInvalidPathChars(字符串路径,布尔值checkAdditional)位于System.IO.Path.GetFileName(字符串路径),位于System.IO.Compression.ZipHelper.EndsWithDirChar(字符串测试)在System.IO.Compression.ZipArchiveEntry.set_FullName(字符串值)在System.IO.Compression.ZipArchiveEntry..ctor(ZipArchive存档,ZipCentralDirectoryFileHeader cd)位于System.IO.Compression.ZipArchive.ReadCentralDirectory()在System.IO.Compression.ZipArchive.get_Entries()在ZipLibraryConsole.MicrosoftExtraction.RecursiveExtract(StreamfileToExtract,Int32 maxDepthLevel,附件att)C:\ Users \ myUser \ Documents \ Visual Studio2015 \ Projects \ ZipLibraryConsole \ ZipLibraryConsole \ MicrosoftExtraction.cs:line47
这是已实现的代码的片段:
var zipArchive = new ZipArchive(fileToExtract, ZipArchiveMode.Read);
try
{
foreach (var zipEntry in zipArchive.Entries) // the exception is thrown here, there is no chance to process valid entries at all
{
// Do something and extract the file
}
catch (ArgumentException exception)
{
Console.WriteLine(
String.Format("Failed to complete the extraction. At least one path contains invalid characters for the Operating System: {0}{1}", att.Name, att.Extention));
}
使用System.Reflection,您至少可以隐藏错误,尽管您最多只能获得路径中包含非法字符的条目。
添加此类并使用archive.GetRawEntries()而不是archive.Entries
public static class ZipArchiveHelper
{
private static FieldInfo _Entries;
private static MethodInfo _EnsureDirRead;
static ZipArchiveHelper()
{
_Entries = typeof(ZipArchive).GetField("_entries", BindingFlags.NonPublic | BindingFlags.Instance);
_EnsureDirRead = typeof(ZipArchive).GetMethod("EnsureCentralDirectoryRead", BindingFlags.NonPublic | BindingFlags.Instance);
}
public static List<ZipArchiveEntry> GetRawEntries(this ZipArchive archive)
{
try { _EnsureDirRead.Invoke(archive, null); } catch { }
return (List<ZipArchiveEntry>)_Entries.GetValue(archive);
}
}
try-catch很丑陋,如果它使您感到烦恼,则可以捕获特定的异常。根据以上评论,此问题已在.NET Core中修复。
此修复https://www.codeproject.com/Tips/1007398/Avoid-Illegal-Characters-in-Path-error-in-ZipArchi和https://gist.github.com/rdavisau/b66df9c99a4b11c5ceff的信用>
ZipFile.ExtractToDirectory "Illegal characters in path"上具有非法字符(不仅仅是zip文件)的路径的更多指针