如何在Python中检测文件是否为二进制(非文本)?
我想知道怎么在Python中判断一个文件是否是二进制文件(非文本文件)?
我在Python中查找一大堆文件,但总是会在二进制文件中找到匹配的内容。这让输出结果看起来非常乱。
我知道可以用 grep -I
来处理,但我需要对数据做的事情比grep能做到的要多。
以前,我会搜索大于 0x7f
的字符,但现在的系统上,像 utf8
这样的编码让这个方法行不通。理想情况下,我希望这个解决方案能快一点。
21 个回答
35
如果你在用python3并且使用utf-8编码,那就很简单。你只需要以文本模式打开文件,如果遇到UnicodeDecodeError
错误,就停止处理。Python3在文本模式下处理文件时会使用unicode编码,而在二进制模式下则使用字节数组。如果你的编码无法解码某些文件,那么很可能会出现UnicodeDecodeError
错误。
举个例子:
try:
with open(filename, "r") as f:
for l in f:
process_line(l)
except UnicodeDecodeError:
pass # Fond non-text data
82
又一种方法,基于file(1)的行为:
>>> textchars = bytearray({7,8,9,10,12,13,27} | set(range(0x20, 0x100)) - {0x7f})
>>> is_binary_string = lambda bytes: bool(bytes.translate(None, textchars))
示例:
>>> is_binary_string(open('/usr/bin/python', 'rb').read(1024))
True
>>> is_binary_string(open('/usr/bin/dh_python3', 'rb').read(1024))
False
51
你还可以使用 mimetypes 这个模块:
import mimetypes
...
mime = mimetypes.guess_type(file)
列出二进制的 MIME 类型其实很简单。比如,Apache 自带一个 mime.types 文件,你可以把它解析成两个列表,一个是二进制类型,一个是文本类型,然后检查一下某个 MIME 类型是属于文本列表还是二进制列表。