gri*_*eve 96 python binary file
如何在python中判断文件是否为二进制(非文本)?我在python中搜索大量文件,并继续在二进制文件中获取匹配.这使得输出看起来非常混乱.
我知道我可以使用grep -I,但是我使用的数据比grep允许的更多.
在过去,我会搜索大于0x7f的字符,但utf8等在现代系统中使这不可能.理想情况下,解决方案会很快,但任何解决方案都可以.
jfs*_*jfs 56
另一种基于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))
Run Code Online (Sandbox Code Playgroud)
例:
>>> is_binary_string(open('/usr/bin/python', 'rb').read(1024))
True
>>> is_binary_string(open('/usr/bin/dh_python3', 'rb').read(1024))
False
Run Code Online (Sandbox Code Playgroud)
Gav*_*Roy 37
您还可以使用mimetypes模块:
import mimetypes
...
mime = mimetypes.guess_type(file)
Run Code Online (Sandbox Code Playgroud)
编译二进制mime类型列表相当容易.例如,Apache使用mime.types文件进行分发,您可以将其解析为一组列表,二进制文本和文本,然后检查mime是否在您的文本或二进制列表中.
sky*_*ing 12
如果你正在使用带有utf-8的python3,它是直接的,只需在文本模式下打开文件,如果你得到一个就停止处理UnicodeDecodeError
.Python3将在文本模式下处理文件时使用unicode(以及二进制模式下的bytearray) - 如果您的编码无法解码任意文件,则很可能会得到UnicodeDecodeError
.
例:
try:
with open(filename, "r") as f:
for l in f:
process_line(l)
except UnicodeDecodeError:
pass # Fond non-text data
Run Code Online (Sandbox Code Playgroud)
小智 10
试试这个:
def is_binary(filename):
"""Return true if the given filename is binary.
@raise EnvironmentError: if the file does not exist or cannot be accessed.
@attention: found @ http://bytes.com/topic/python/answers/21222-determine-file-type-binary-text on 6/08/2010
@author: Trent Mick <TrentM@ActiveState.com>
@author: Jorge Orpinel <jorge@orpinel.com>"""
fin = open(filename, 'rb')
try:
CHUNKSIZE = 1024
while 1:
chunk = fin.read(CHUNKSIZE)
if '\0' in chunk: # found null byte
return True
if len(chunk) < CHUNKSIZE:
break # done
# A-wooo! Mira, python no necesita el "except:". Achis... Que listo es.
finally:
fin.close()
return False
Run Code Online (Sandbox Code Playgroud)
这是一个使用Unix 文件命令的建议:
import re
import subprocess
def istext(path):
return (re.search(r':.* text',
subprocess.Popen(["file", '-L', path],
stdout=subprocess.PIPE).stdout.read())
is not None)
Run Code Online (Sandbox Code Playgroud)
用法示例:
>>> istext('/etc/motd') True >>> istext('/vmlinuz') False >>> open('/tmp/japanese').read() '\xe3\x81\x93\xe3\x82\x8c\xe3\x81\xaf\xe3\x80\x81\xe3\x81\xbf\xe3\x81\x9a\xe3\x81\x8c\xe3\x82\x81\xe5\xba\xa7\xe3\x81\xae\xe6\x99\x82\xe4\xbb\xa3\xe3\x81\xae\xe5\xb9\x95\xe9\x96\x8b\xe3\x81\x91\xe3\x80\x82\n' >>> istext('/tmp/japanese') # works on UTF-8 True
它有不能移植到Windows的缺点(除非你有像file
命令那样的东西),并且必须为每个文件生成一个外部进程,这可能不太合适.
小智 6
我们可以使用 python 本身来检查文件是否是二进制文件,因为如果我们尝试以文本模式打开二进制文件,它会失败
def is_binary(file_name):
try:
with open(file_name, 'tr') as check_file: # try open file in text mode
check_file.read()
return False
except: # if fail then file is non-text (binary)
return True
Run Code Online (Sandbox Code Playgroud)
尝试使用当前维护的python-magic,它与 @Kami Kisiel 的答案中的模块不同。这确实支持包括 Windows 在内的所有平台,但您将需要libmagic
二进制文件。自述文件中对此进行了解释。
与mimetypes模块不同,它不使用文件的扩展名,而是检查文件的内容。
>>> import magic
>>> magic.from_file("testdata/test.pdf", mime=True)
'application/pdf'
>>> magic.from_file("testdata/test.pdf")
'PDF document, version 1.2'
>>> magic.from_buffer(open("testdata/test.pdf").read(1024))
'PDF document, version 1.2'
Run Code Online (Sandbox Code Playgroud)
使用binaryornot库(GitHub).
它非常简单,基于此stackoverflow问题中的代码.
实际上你可以用两行代码来编写这个代码,但是这个包可以让你不必编写和彻底测试那两行代码和各种奇怪的文件类型,跨平台.
小智 5
from binaryornot.check import is_binary
is_binary('filename')
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
56264 次 |
最近记录: |