编码zipfile时出错

sha*_*asj 1 python encoding zipfile

我有几个文件,我想用zipfile压缩,但当文件的名称有图形重音时出现一个错误.

我的文件列表:

  • AdrianoAraújo.zip
  • AndréCerqueira.zip
  • PauloHenriqueGuiné.zip

当我在filez.zip中压缩这些文件时:

  • Adriano Ara·jo.zip
  • AndrÚCerqueira.zip
  • PauloGuinÚ.zip

代码:

from zipfile_infolist import print_info
import zipfile
import os
import fileinput
import glob
files1 = glob.glob( '*.zip' )
for name in files1:
   zf = zipfile.ZipFile('C:\Users\sergioH\files.zip', mode='a')
   try:
      zf.write('%(name)s' % {'name':name})
   finally:
      zf.close()
      print
Run Code Online (Sandbox Code Playgroud)

怎么解决这个?

Mar*_*ers 6

zipfile模块文档:

注意:ZIP文件没有正式的文件名编码.如果您有unicode文件名,则必须先将它们转换为所需编码的字节字符串,然后再将其传递给它们write().WinZip将所有文件名解释为CP437中编码的文件名,也称为DOS Latin.

您似乎在使用未编码到CP437的文件名; 您可能希望为glob()命令使用Unicode文件路径,因此Python返回Unicode文件名,然后在压缩时编码为CP437:

from string import maketrans

def encode_cp437(s, _noqmarks=maketrans('?', '_')):
    return s.encode('cp437', errors='replace').translate(_noqmarks)

files1 = glob.glob(u'*.zip')  # unicode path
with zipfile.ZipFile('C:\Users\sergioH\files.zip', mode='a') as zf:
    for name in files1:
        zf.write(name, encode_cp437(name))
Run Code Online (Sandbox Code Playgroud)

请注意,我使用该ZipFile对象作为上下文管理器来确保它自动关闭,并且只为列表中的每个文件名打开一次.

errors='replace'即使有不能编码CP437的代码点,我也习惯强制编码成功.任何此类代码点都被带有?问号的Python替换,这些问号在某些文件系统上也是不允许的,所以我们用_下划线替换那些.警告:这可能导致文件名重复!