python - 使用 Python 提取文件名中包含无效字符的文件

标签 python unicode encoding filenames zip

我使用 python 的 zipfile 模块来提取 .zip 存档(让我们以 http://img.dafont.com/dl/?f=akvaleir 中的这个文件为例。)

f = zipfile.ZipFile('akvaleir.zip', 'r')
for fileinfo in f.infolist():
    print fileinfo.filename
    f.extract(fileinfo, '.')

它的输出:

Akval�ir_Normal_v2007.ttf
Akval�ir, La police - The Font - Fr - En.pdf

这两个文件在提取后都无法访问,因为它们的文件名中存在无效的编码字符。问题是 zipfile 模块没有指定输出文件名的选项。

但是,“unzip akvaleir.zip”很好地转义了文件名:

root@host:~# unzip akvaleir.zip 
Archive:  akvaleir.zip
  inflating: AkvalВir_Normal_v2007.ttf  
  inflating: AkvalВir, La police - The Font - Fr - En.pdf  

我尝试在我的 python 程序中捕获“unzip -l akvaleir.zip”的输出,这两个文件名是:

Akval\xd0\x92ir_Normal_v2007.ttf
Akval\xd0\x92ir, La police - The Font - Fr - En.pdf

如何在不捕获“unzip -l akvaleir.zip”输出的情况下像 unzip 命令一样获得正确的文件名?

最佳答案

我花了一些时间,但我想我找到了答案。

我以为这个词应该是 Akvaléir。我在法语中找到了关于它的页面描述。当我使用你的代码片段时,我有一个类似的字符串

>>> fileinfo.filename
'Akval\x82ir, La police - The Font - Fr - En.pdf'
>>> 

这不适用于 UTF8、Latin-1、CP-1251 或 CP-1252 编码。然后我发现 CP863 可能是加拿大编码,所以这可能来自加拿大法语。

>>> print unicode(fileinfo.filename, "cp863").encode("utf8")
Akvaléir, La police - The Font - Fr - En.pdf
>>> 

但是,我随后阅读了 Zip file format specification这说

The ZIP format has historically supported only the original IBM PC character encoding set, commonly referred to as IBM Code Page 437.

...

If general purpose bit 11 is set, the filename and comment must support The Unicode Standard, Version 4.1.0 or greater using the character encoding form defined by the UTF-8 storage specification.

测试它给出了与加拿大代码页相同的答案

>>> print unicode(fileinfo.filename, "cp437").encode("utf8")
Akvaléir, La police - The Font - Fr - En.pdf
>>>

我没有 Unicode 编码的 zip 文件,我也不打算创建一个来找出答案,所以我假设所有的 zip 文件都有 cp437 编码。

import shutil
import zipfile

f = zipfile.ZipFile('akvaleir.zip', 'r')
for fileinfo in f.infolist():
    filename = unicode(fileinfo.filename, "cp437")
    outputfile = open(filename, "wb")
    shutil.copyfileobj(f.open(fileinfo.filename), outputfile)

在我的 Mac 上

 109936 Nov 27 01:46 Akvale??ir_Normal_v2007.ttf
  25244 Nov 27 01:46 Akvale??ir, La police - The Font - Fr - En.pdf

完成哪个制表符

ls Akvale\314\201ir

并在我的文件浏览器中显示一个漂亮的“é”。

关于python - 使用 Python 提取文件名中包含无效字符的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1807063/

相关文章:

encoding - 编码和字符集有什么区别?

Python POST 请求 - 设置整个原始帖子正文?

android - 带有 Python 后端的 Google Endpoints Android

python - 如何使用python从unicode转换

java - 自动将 Unicode 字符映射到类似的 EBCDIC 1047 字符

regex - 我们应该考虑将范围 [a-z] 用作错误吗?

Java编码/解码一个字符串到/从一个长

encoding - 如何从十六进制值识别编码?

python - 如何使数据类中的属性只读?

python - 将图像存储在内存中,然后写入磁盘