如何确定一个流是否为文本或二进制在Python?(How to determine whether

2019-10-19 20:02发布

有没有一种方法来确定(测试,检查或分类)是否一个文件(或字节流,或其他类似文件的对象)是文本或二进制,类似file命令在Unix的魔力,在实际大多数情况下?

动机:尽管猜测应该避免 ,其中Python 可以判断这一点,我想利用能力。 人们可以覆盖的情况下有用的量和处理异常。

优先将给予跨平台或纯Python的方法。 一种方式是蟒蛇魔法但是这取决于Cygwin的Windows上,和一般libmagic。

Answer 1:

file手册页:

印刷通常会包含单词文本的一个(该文件仅包含打印字符和一些常见的控制字符和可能是安全的ASCII终端上读取),可执行文件(该文件包含在一个形式编译程序的结果的类型理解一些UNIX内核或其他),或数据意味着任何东西(数据通常是``二进制“”或不可打印的)。

看到你只想确定它是否是文本或二进制,我只想检查,如果流中的每个字符是否可打印

import string
all(c in string.printable for c in stream)

我不认为你会永远能够得到这个100%正确的,但是这应该是相当准确的。 您是否需要处理,虽然Unicode编码?

编辑 -支持Unicode是有点棘手,但如果你有一组可能的编码的,那么你可以测试是否成功文件从每一个解码,检查前如果所有的字符可打印

import string
import unicodedata

encodings = 'ascii', 'utf-8', 'utf-16'

test_strings = '\xf0\x01\x01\x00\x44', 'this is a test', 'a utf-8 test \xe2\x98\x83'

def attempt_decode(s, encodings):
    for enc in encodings:
        try:
            return s.decode(enc), enc
        except UnicodeDecodeError:
            pass
    return s, 'binary'

def printable(s):
    if isinstance(s, unicode):
        return not any(unicodedata.category(c) in ['Cc'] for c in s)
    return all(c in string.printable for c in s)

for s in test_strings:
    result, enc = attempt_decode(s, encodings)
    if enc != 'binary':
        if not printable(result):
            result, enc = s, 'binary'
    print enc + ' - ' + repr(result)

这导致:

binary - '\xf0\x01\x01\x00D'
ascii - u'this is a test'
utf-8 - u'a utf-8 test \u2603'


文章来源: How to determine whether a stream is text or binary in Python?