我正在解压一个中等大小的 ZIP 文件,其中包含数千个名称不同的小文件。其中一些文件的名称包含非法字符,如“:”。这导致 Windows 在尝试解压这些文件并将其复制到目标文件夹时出现问题。
它抛出了Error 0x80070057
。网上的一些资料声称这是由于磁盘空间不足造成的,但就我的情况而言,这绝对不是事实。此错误很可能是由于文件名称中包含非法字符,因为其他文件复制时没有问题。
然后 Windows 要求我Try Again
或Skip
,一旦我选择重试,它就会用“_”替换任何非法字符,从而很好地解决问题。
我的问题是如何防止 Windows 询问我数千次?我尝试选中复选框Do this for all current items
,但没有效果。
这个问题与这个。一是因为我没有使用 7Zip,而是使用 Windows 内置的提取程序。二是因为那个问题是关于解决名称冲突,而这个问题是关于从文件名中删除非法字符。
答案1
.Net
在System.IO.Compression
命名空间。它们提供各种方法,让您对创建、修改和提取有更高级别的控制。
为了在提取过程中将任何非法文件名转换为合法文件名,使用的方法/属性将是:
ZipFile.OpenRead()
- 以 ZipArchvie 格式打开 zip 文件
ZipArchive.Entries
- 获取文件中各个条目的列表
ZipFileExtensions.ExtractToFile()
- 提取每个条目有机会修改提取文件的名称
编辑:PowerShell 代码用于纠正提取过程中的非法文件名
由于您找到了适合您的 Python 解决方案,因此我花了一些时间尝试这些类,因为它们对我来说很新。但为了满足好奇和未来的读者,这里是直接的 PowerShell/.net 代码。
此代码将打开一个 .zip 文件作为压缩档案并替换每个名称/全名中的任何非法字符Zip存档条目_
在提取之前使用下划线( )字符。
此处的输入是硬编码的,以保持对文件操作的关注,但代码可以作为功能或上下文菜单项的基础。
### User Input ###
$ZipPath = 'C:\Users\Whoever\Wherever\Illegal.zip' ### Path to .zip file
$ExtractPath = 'C:\Users\Whoever\NonExisting' ### Path of target directory
### Load required assemblies
Add-Type -AssemblyName System.IO.Compression
Add-Type -AssemblyName System.IO.Compression.FileSystem
### Construct regex character class to match illegal characters
$IllegalChars = '[{0}]' -f ( -join [IO.Path]::GetInvalidFileNameChars().ForEach{[Regex]::Escape($_)})
### Create target directory if it doesn't exist
If (!(Test-Path $ExtractPath))
{
mkdir $ExtractPath -Force | out-null
}
### Ensure ExtractPath is fully-qualified for subsequent operations
$ExtractPath = [IO.Path]::GetFullPath($ExtractPath)
$Archive = [IO.Compression.ZipFile]::OpenRead($ZipPath)
$Archive.Entries | ForEach{
If ($_.Name -eq $_.FullName) ### no subdirectory
{
[IO.Compression.ZipFileExtensions]::ExtractToFile($_, (Join-Path $ExtractPath ($_.Name -replace ($IllegalChars,'_'))))
}
Else ### subdirectory
{
$ChildPath = $_.FullName.Split('/') -replace ($IllegalChars,'_') -join [io.Path]::DirectorySeparatorChar
$subFolder = Split-Path $ChildPath
If (!(Test-Path $subFolder))
{
mkdir $subFolder -Force | out-null
}
[IO.Compression.ZipFileExtensions]::ExtractToFile($_, (Join-Path $ExtractPath $ChildPath))
}
}