使用Unicode文件名在Linux中创建文件

时间:2015-06-05 13:54:53

标签: python linux windows unicode

我创建了一个Python脚本,使用“email”模块读取电子邮件文件并将其附件提取到文件系统,压缩解压缩的文件并将Zip文件通过电子邮件发送给某人。

附件可能包含Unicode文件名,例如中文或日文。我发现模块“email.header.decode_header”可以检索文件名及其编码。例如:

decode_header(payload.get_filename())

将产生:

[('2015\xe5\xb9\xb4\xe6\xb5\x81\xe5\xb9\xb4_Test.pages', 'utf-8')]

哪个文件名由UTF-8编码。或

[('\x1b$B%Q%=%3%s;q;:4IM}BfD"!J\x1b(BS&T HK\x1b$B!K\x1b(B_\x1b$B8=COD4C#\x1b(BPC.xls', 'iso-2022-jp')] 

包含日文字符。

在脚本中,我将文件名转换为UTF-8并保存在文件系统(Linux)中,然后创建一个Zip文件,然后通过电子邮件发送Zip文件。当用户在Windows中检索并解压缩zip文件时,Zip文件中的文件名变为垃圾。

我搜索Google和StackOverflow我发现Windows文件系统是Unicode而不是UTF-8。因此,我可以在MacOS上打开Zip文件而不会出现问题,但在Windows上会出现问题。我还尝试更改脚本以Unicode格式命名文件:

filename = unicode('\x1b$B%Q%=%3%s;q;:4IM}BfD"!J\x1b(BS&T HK\x1b$B!K\x1b(B_\x1b$B8=COD4C#\x1b(BPC.xls', 'iso-2022-jp')
f = open(filename, 'wb')
....

当我在Python shell中尝试上述命令时,我可以毫无问题地创建文件。但是,当我将确切的命令放入我的脚本时,出现错误

UnicodeEncodeError: 'ascii' codec can't encode characters in position 4-6: ordinal not in range(128)

显示。

是否有人可以建议我如何解决此问题,以便我可以创建一个Zip文件,该文件可以在Windows中以正确的名称打开。

2 个答案:

答案 0 :(得分:0)

恐怕没有好的解决方案。 AFAIK,ZIP中文件的名称是8位字符串。因此,您必须使用您选择的编码对其进行编码,并且将在Linux和Mac上正确理解utf8。

在Windows上,您可以做的最好的事情是翻译 zip文件:

  • 提取所有文件
  • 表示每个文件
    • 将其名称作为8位字符串
    • 将名称解码为utf8为unicode字符串
    • 将其编码为8位字符串,在Windows上使用本机编码(通常是latin1语言的windows-1252)
    • 使用新名称重命名文件
  • 使用重命名的文件构建新的zip

或者尝试使用另一种格式的存档,因为7z格式应该接受unicode名称。

答案 1 :(得分:0)

最后,我发现了为什么我可以在Python解释器中成功创建文件但在我的Python脚本中失败的问题。我发现Python解释器的LANG环境是“en_US.UTF8”,但在我的Python脚本中是“C”。

import os
print os.environ['LANG']

我认为当我在Python脚本中使用中文或日文文件名创建文件时会产生错误。

我尝试通过以下方式运行我的Python脚本:

env LANG=en_US.UTF8 myscript.py

将LANG更改为UTF-8。问题解决了。