在我的小项目中,我必须识别目录中的文件类型。因此,我使用了python-magic模块并完成了以下操作:
from Tkinter import Tk
from tkFileDialog import askdirectory
def getDirInput():
root = Tk()
root.withdraw()
return askdirectory()
di = getDirInput()
print('Selected Directory: ' + di)
for f in os.listdir(di):
m = magic.Magic(magic_file='magic')
print 'Type of ' + f + ' --> ' + m.from_file(f)但是,当我将python-magic文件名传递给from_file()函数时,它似乎不能接受unicode文件名。下面是一个示例输出:
Selected Directory: C:/Users/pruthvi/Desktop/vidrec/temp
Type of log.txt --> ASCII English text, with very long lines, with CRLF, CR line terminators
Type of TAEYEON 태연_ I (feat. Verbal Jint)_Music Video.mp4 --> cannot open `TAEYEON \355\234\227_ I (feat. Verbal Jint)_Music Video.mp4' (No such file or directory)
Type of test.py --> a python script text executable您可以看到,python-magic未能标识第二个文件TAEYEON...的类型,因为其中包含unicode字符。它将태연字符显示为\355\234\227,而我在这两种情况下都传递了相同的字符。如何克服这个问题,并找到具有Unicode字符的文件类型?谢谢
发布于 2016-01-17 12:35:35
但似乎python魔术不能接受unicode文件名。
对,是这样。事实上,Windows上的大多数跨平台软件都无法处理文件名中的非ASCII字符。
这是因为C标准库对所有文件名都使用字节字符串,而Windows使用Unicode字符串(从技术上讲,UTF-16代码单元字符串,但这里的区别并不重要)。当使用C标准库的软件以字节为基础的字符串打开文件时,MS运行时将其自动转换为Unicode字符串,使用依赖于Windows安装区域设置的编码(名称混乱的‘ANSI’代码页)。您的ANSI代码页可能是1252,它不能编码韩国字符,因此不可能使用该文件名。不幸的是,ANSI代码页从来不像UTF-8那样合理,因此它永远不能包含所有可能的Unicode字符。
Python的特殊之处在于它对Windows文件名有额外的支持,它绕过了C标准库,直接为Unicode文件名调用底层的Win32 API。因此,您可以使用例如open()传递一个unicode字符串,它将对所有文件名都有效。
然而,python-magic的from_file调用并没有从from_file打开文件,而是将文件名传递给用纯C编写的libmagic库,libmagic没有用于libmagic的特殊的Windows文件名编码路径,所以这是失败的。
我建议您自己从Python中打开该文件并使用magic.from_buffer。
发布于 2016-01-17 09:33:01
来自魔术模块的响应似乎表明您的字符在某个地方被错误地翻译了--只显示了字符串的一半,并且태的字节顺序是错误的--至少应该是\355\227\234。
由于这是在Windows上,这会引起UTF-16字节级的警报铃声.
也许可以通过编码到UTF-16来解决这个问题。正如其他评论者所建议的那样,您需要在目录前加上前缀。
input_encoding = locale.getpreferredencoding()
u_di = di.decode(input_encoding)
m = magic.Magic(magic_file='magic') # only needs to be initialised once
for f in os.listdir(u_di):
fq_f = os.path.join(u_di, f)
utf16_fq_f = fq_f.encode("UTF-16LE")
print m.from_file(utf16_fq_f)https://stackoverflow.com/questions/34836792
复制相似问题