【问题标题】:How to determine if file is opened in binary or text mode?如何确定文件是以二进制还是文本模式打开的?
【发布时间】:2017-06-16 08:49:36
【问题描述】:

给定一个文件对象,我如何确定它是以字节模式(read 返回bytes)还是以文本模式(read 返回str)打开的?它应该适用于阅读和写作。

换句话说:

>>> with open('filename', 'rb') as f:
...     is_binary(f)
...
True

>>> with open('filename', 'r') as f:
...     is_binary(f)
...
False

Another question 听起来不相关。这个问题是关于从文件的内容中猜测文件是否是二进制文件。)

【问题讨论】:

    标签: python


    【解决方案1】:

    文件对象有一个.mode attribute:

    def is_binary(f):
        return 'b' in f.mode
    

    这将测试限制为文件; TextIOBytesIO 等内存文件对象没有该属性。你也可以测试appropriate abstract base classes:

    import io
    
    def is_binary(f):
        return isinstance(f, (io.RawIOBase, io.BufferedIOBase))
    

    或相反

    def is_binary(f):
        return not isinstance(f, io.TextIOBase)
    

    【讨论】:

    • 非常好,也感谢文档链接并将我指向 io 模块。我只在词汇表中找到了file object 的定义,这很肤浅....另外,现在我想起来了,另一种pythonic方式可能只是尝试阅读,如果失败则捕获异常。
    • 由于文件可能是没有.mode 属性的类文件对象,因此更安全的测试方法是:if 'b' not in getattr(file, 'mode', 'b')
    【解决方案2】:

    对于以读取方式打开的流,确定其模式的最可靠方法可能是实际读取

    def is_binary(f):
        return isinstance(f.read(0), bytes)
    

    虽然它确实有一个警告,如果流已经关闭(这可能会引发IOError)它将无法工作,但它可以可靠地确定任何自定义文件类对象的二进制性,这些对象既不是从适当的io 扩展的ABC 也不提供mode 属性。

    如果只需要 Python 3 支持,那么在明确区分字节和文本的情况下,还可以确定可写流的文本/二进制模式:

    def is_binary(f):
        read = getattr(f, 'read', None)
        if read is not None:
            try:
                data = read(0)
            except (TypeError, ValueError):
                pass # ValueError is also a superclass of io.UnsupportedOperation
            else:
                return isinstance(data, bytes)
        try:
            # alternatively, replace with empty text literal
            # and swap the following True and False.
            f.write(b'')
        except TypeError:
            return False
        return True
    

    除非您要经常测试流是否处于二进制模式(这是不必要的,因为流的二进制性在对象的生命周期内不应改变),我怀疑由于广泛使用捕获异常将是一个问题(不过,您当然可以针对更可能的路径进行优化)。

    【讨论】:

      【解决方案3】:

      有一个名为 mimetypes 的库,其中guess_type 返回返回值是一个元组(类型,编码),如果无法猜测类型(缺少或未知后缀),则类型为 None 或形式为 'type 的字符串/子类型'

      import mimetypes
      file= mimetypes.guess_type(file)
      

      【讨论】:

      • 这与文件的内容无关。这是关于文件的打开方式。请仔细阅读这个问题,他们特别提到了另一个问题,这可能是一个答案,但这不是那个问题
      猜你喜欢
      • 2012-08-04
      • 2012-05-31
      • 1970-01-01
      • 2010-10-28
      • 2015-07-27
      • 1970-01-01
      • 1970-01-01
      • 2015-10-07
      • 1970-01-01
      相关资源
      最近更新 更多