C# ZipArchive 路径中的非法字符
C# ZipArchive Illegal characters in path
给定以下代码:
using (var data = new MemoryStream(bytes))
using(var archive = new ZipArchive(data))
{
foreach (var entry in archive.Entries)
{
entry.FullName.Log();
}
...
抛出的异常是:
Illegal characters in path.
在 foreach
行。
如何找出受影响的条目?每当我尝试访问条目时,它都会抛出异常。这个特定的存档似乎是从 Mac 创建的,因为它包含 _MACOSX
文件夹。
堆栈跟踪:
[ArgumentException: Illegal characters in path.]
System.IO.Path.CheckInvalidPathChars(String path, Boolean checkAdditional) +14351233
System.IO.Path.GetFileName(String path) +29
System.IO.Compression.ZipHelper.EndsWithDirChar(String test) +9
System.IO.Compression.ZipArchiveEntry.set_FullName(String value) +93
System.IO.Compression.ZipArchiveEntry..ctor(ZipArchive archive, ZipCentralDirectoryFileHeader cd) +228
System.IO.Compression.ZipArchive.ReadCentralDirectory() +172
System.IO.Compression.ZipArchive.get_Entries() +36
同意评论。您确定您的文件完好无损并且来自兼容平台吗?如果您使用例如打开您的存档会发生什么WinRar ?
我之前测试了下面的代码,并像您一样使用内存流成功地修改了它,我相信您的版本应该也能正常工作..
[Test]
public void TestZipper()
{
using (var dataFromFile = new FileStream("d:\lx\MyZip.ZIP", FileMode.Open))
{
var dataInMemory = new MemoryStream();
dataFromFile.CopyTo(dataInMemory);
using (var archive = new ZipArchive(dataInMemory))
{
foreach (var entry in archive.Entries)
{
Debug.WriteLine(entry.FullName);
}
Assert.That(MyZipListIsComplete(archive.Entries));
}
}
}
您的异常被抛出,因为 ZipArchive.Entries
试图读取 zip 中央目录以便为每个条目构造一个 ZipArchiveEntry
。 ZipArchiveEntry
构造函数正在调用 Path.GetFileName
,后者调用 Path.CheckInvalidPathChars
,如果路径包含 [=15=]
.
,则抛出
尽管在读取中央目录的过程中出现异常会使 ZipArchive
留下部分填充的条目列表,但似乎没有任何方法可以在不触发读取的情况下读取它中央目录,除非你使用调试器/反射读取 _entries
或 _entriesCollection
。这将告诉您哪些条目成功了,这可能会缩小失败的条目的范围。如果您要达到这些长度,调试 .Entries
调用会准确告诉您哪个条目失败。
看起来在不同平台上以不同方式对待路径的相关问题是 recognised in 2015, and as part of that a change was made to get the file name without calling Path.CheckInvalidPathChars
,这应该可以避免该问题(如果您尝试将此条目写入文件Windows,但至少 .Entries
不应该抛出)。不幸的是,这仅在 .NET Core 中引入。
给定以下代码:
using (var data = new MemoryStream(bytes))
using(var archive = new ZipArchive(data))
{
foreach (var entry in archive.Entries)
{
entry.FullName.Log();
}
...
抛出的异常是:
Illegal characters in path.
在 foreach
行。
如何找出受影响的条目?每当我尝试访问条目时,它都会抛出异常。这个特定的存档似乎是从 Mac 创建的,因为它包含 _MACOSX
文件夹。
堆栈跟踪:
[ArgumentException: Illegal characters in path.]
System.IO.Path.CheckInvalidPathChars(String path, Boolean checkAdditional) +14351233
System.IO.Path.GetFileName(String path) +29
System.IO.Compression.ZipHelper.EndsWithDirChar(String test) +9
System.IO.Compression.ZipArchiveEntry.set_FullName(String value) +93
System.IO.Compression.ZipArchiveEntry..ctor(ZipArchive archive, ZipCentralDirectoryFileHeader cd) +228
System.IO.Compression.ZipArchive.ReadCentralDirectory() +172
System.IO.Compression.ZipArchive.get_Entries() +36
同意评论。您确定您的文件完好无损并且来自兼容平台吗?如果您使用例如打开您的存档会发生什么WinRar ?
我之前测试了下面的代码,并像您一样使用内存流成功地修改了它,我相信您的版本应该也能正常工作..
[Test]
public void TestZipper()
{
using (var dataFromFile = new FileStream("d:\lx\MyZip.ZIP", FileMode.Open))
{
var dataInMemory = new MemoryStream();
dataFromFile.CopyTo(dataInMemory);
using (var archive = new ZipArchive(dataInMemory))
{
foreach (var entry in archive.Entries)
{
Debug.WriteLine(entry.FullName);
}
Assert.That(MyZipListIsComplete(archive.Entries));
}
}
}
您的异常被抛出,因为 ZipArchive.Entries
试图读取 zip 中央目录以便为每个条目构造一个 ZipArchiveEntry
。 ZipArchiveEntry
构造函数正在调用 Path.GetFileName
,后者调用 Path.CheckInvalidPathChars
,如果路径包含 [=15=]
.
尽管在读取中央目录的过程中出现异常会使 ZipArchive
留下部分填充的条目列表,但似乎没有任何方法可以在不触发读取的情况下读取它中央目录,除非你使用调试器/反射读取 _entries
或 _entriesCollection
。这将告诉您哪些条目成功了,这可能会缩小失败的条目的范围。如果您要达到这些长度,调试 .Entries
调用会准确告诉您哪个条目失败。
看起来在不同平台上以不同方式对待路径的相关问题是 recognised in 2015, and as part of that a change was made to get the file name without calling Path.CheckInvalidPathChars
,这应该可以避免该问题(如果您尝试将此条目写入文件Windows,但至少 .Entries
不应该抛出)。不幸的是,这仅在 .NET Core 中引入。