gpt4 book ai didi

c# - 当其中一个包含非法字符时,如何获取 ZipArchive 的有效条目?

转载 作者:行者123 更新时间:2023-12-05 07:45:00 29 4
gpt4 key购买 nike

我正在使用 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 表达式应用过滤器以忽略无效条目(也有相同的异常(exception)):

    var entries = zipArchive.Entries.Where(a => 
    a.FullName.IndexOfAny(Path.GetInvalidFileNameChars() ) == -1);

这些都没有帮助,我每次得到的异常如下:

at System.IO.Path.CheckInvalidPathChars(String path, Boolean checkAdditional) at System.IO.Path.GetFileName(String path) at System.IO.Compression.ZipHelper.EndsWithDirChar(String test) at System.IO.Compression.ZipArchiveEntry.set_FullName(String value) at System.IO.Compression.ZipArchiveEntry..ctor(ZipArchive archive, ZipCentralDirectoryFileHeader cd) at System.IO.Compression.ZipArchive.ReadCentralDirectory() at System.IO.Compression.ZipArchive.get_Entries() at ZipLibraryConsole.MicrosoftExtraction.RecursiveExtract(Stream fileToExtract, Int32 maxDepthLevel, Attachment att) in C:\Users\myUser\Documents\Visual Studio 2015\Projects\ZipLibraryConsole\ZipLibraryConsole\MicrosoftExtraction.cs:line 47

这是已实现代码的片段:

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 中修复的。 (更新:已确认此问题已在 .Net Core 3.1 中修复,可能更早)。

此(部分)修正归功于 https://www.codeproject.com/Tips/1007398/Avoid-Illegal-Characters-in-Path-error-in-ZipArchihttps://gist.github.com/rdavisau/b66df9c99a4b11c5ceff

关于修复带有非法字符的路径(不仅仅是 zip 文件)的更多指示在 ZipFile.ExtractToDirectory "Illegal characters in path"

关于c# - 当其中一个包含非法字符时,如何获取 ZipArchive 的有效条目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42262013/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com