c# - 目录存在时 ZipFile.ExtractToDirectory 会抛出异常吗?
问题描述
根据Microsoft DocsIOException
,如果要提取 zip 文件的目标目录已经存在,程序应该抛出一个。此外,“备注”部分说,“目标目录不能已经存在。” 然而,
ZipFile.ExtractToDirectory("archive.zip", ".\\output");
即使output
作为目录存在,也可以正常工作(没有例外)。就像是
ZipFile.ExtractToDirectory("archive.zip", "\\");
也可以毫无例外地工作。因此,我试图理解为什么 Microsoft Docs 明确建议应该有例外时没有例外。
注意:我正在运行 .NET 5。
解决方案
看起来像一个文档错误。我为此打开了两个 GitHub 问题,一个用于源代码注释,一个用于从它们创建的文档页面
.NET Core 是开源的,这意味着我们可以检查实际的源代码以了解发生了什么。
ZipFile.ExtractToDirectory实际上调用了ZipFileExtensions.ExtractToDirectory(ZipArchive, String)方法:
public static void ExtractToDirectory(string sourceArchiveFileName, string destinationDirectoryName, Encoding? entryNameEncoding, bool overwriteFiles)
{
if (sourceArchiveFileName == null)
throw new ArgumentNullException(nameof(sourceArchiveFileName));
using (ZipArchive archive = Open(sourceArchiveFileName, ZipArchiveMode.Read, entryNameEncoding))
{
archive.ExtractToDirectory(destinationDirectoryName, overwriteFiles);
}
}
在实际代码中,如果目标目录存在,则不会抛出IOException ,即使文档网站这样说:
/// <exception cref="IOException">An archive entry?s name is zero-length, contains only whitespace, or contains one or more invalid
/// characters as defined by InvalidPathChars. -or- Extracting an archive entry would have resulted in a destination
/// file that is outside destinationDirectoryName (for example, if the entry name contains parent directory accessors).
/// -or- An archive entry has the same name as an already extracted entry from the same archive.</exception>
public static void ExtractToDirectory(this ZipArchive source, string destinationDirectoryName, bool overwriteFiles)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (destinationDirectoryName == null)
throw new ArgumentNullException(nameof(destinationDirectoryName));
foreach (ZipArchiveEntry entry in source.Entries)
{
entry.ExtractRelativeToDirectory(destinationDirectoryName, overwriteFiles);
}
}
它看起来像是docs.microsoft.com
在实际的源文档后面。
为了完整起见,内部 ExtractRelativeToDirectory 方法明确地将现有目标文件夹视为有效案例:
internal static void ExtractRelativeToDirectory(this ZipArchiveEntry source, string destinationDirectoryName, bool overwrite)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (destinationDirectoryName == null)
throw new ArgumentNullException(nameof(destinationDirectoryName));
// Note that this will give us a good DirectoryInfo even if destinationDirectoryName exists:
DirectoryInfo di = Directory.CreateDirectory(destinationDirectoryName);
...
强调:
// 请注意,即使destinationDirectoryName 存在,这也会给我们一个好的DirectoryInfo
推荐阅读
- javascript - 是否可以在上传前同时验证文件大小和扩展名?
- excel - 协调/比较两个表的数据
- python - 替换熊猫数据框中包含引号的字符串
- typescript - 在 image.onload 函数内部,访问类对象和图像对象
- iis - 如何使用 Windows 性能监视器监视 IIS 工作进程
- google-cloud-storage - 客户提供的加密密钥功能不可用(但它是!)
- highcharts - Highcharts:我们如何对动画系列进行排序?
- javascript - 无法设置多张图片
- regex - 如果文本被换行符或标签打断,如何替换文本?
- javascript - 在已经调用的函数中调用函数