【问题标题】:Ignore newline character in binary file with Python?用Python忽略二进制文件中的换行符?
【发布时间】:2016-04-28 02:21:00
【问题描述】:

我像这样打开我的文件:

f = open("filename.ext", "rb") # ensure binary reading with b

我的第一行数据是这样的(使用f.readline()时):

'\x04\x00\x00\x00\x12\x00\x00\x00\x04\x00\x00\x00\xb4\x00\x00\x00\x01\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x18\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00:\x00\x00\x00;\x00\x00\x00<\x00\x00\x007\x00\x00\x008\x00\x00\x009\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\t\x00\x00\x00\n'

问题是,我想逐字节读取此数据 (f.read(4))。在调试时,我意识到当它到达第一行的末尾时,它仍然接受换行符\n,它被用作我读取的以下 int 的第一个字节。我不想简单地使用.splitlines(),因为某些数据内部可能有n,我不想破坏它。顺便说一句,我使用的是 Python 2.7.10。我还读到使用b 参数打开二进制文件“照顾”新行/行尾字符;为什么我不是这样?

这是在控制台中发生的情况,因为文件的位置正好在换行符之前:

>>> d = f.read(4)
>>> d
'\n\x00\x00\x00'
>>> s = struct.unpack("i", d)
>>> s
(10,)

【问题讨论】:

  • 文件的格式到底是什么?换行符是有意的吗?当真正的信息是字节时,换行符只是一个意外吗?那么,阅读有什么问题呢?
  • 好吧,和任何文件一样,行尾都有换行符。每行有多个整数,但按 4 字节为一组读取会出现错误结果,因为当文件的位置在第一行的末尾,就在 \n 之前,下一个 f.read(4)\n 作为第一个字节,接下来的三个字节是第二行(下一行)的前三个字节。
  • 所以基本上换行符是用来格式化/分隔的,不应该读作“数据”?
  • 如果它是一个二进制文件,那么它可能不应该有“行”,如果有,那么“换行”只是被意外解释为换行的数据。
  • readline() 尝试将每个字节解释为一个字符,但有时它只是数据,并不意味着作为字符具有意义。 (asciitable.com 值的含义)。如果您只存储数据,您想将其作为 ONLY 数据读取,即使它具有换行符的“含义”。

标签: python binaryfiles binary-data


【解决方案1】:

(在聊天中与 OP 讨论之后)

似乎文件是二进制格式,而换行符只是被错误解释的值。例如,将10 写入文件时可能会发生这种情况。

这并不意味着换行是有意的,而且很可能不是。您可以忽略它被打印为\n 并将其用作数据。

【讨论】:

    【解决方案2】:

    您应该能够替换表明它是换行符的字节。

    >>> d = f.read(4).replace(b'\x0d\x0a', b'') #\r\n should be bytes b'\x0d\x0a'
    >>> diff = 4 - len(d)
    >>> while diff > 0: # You can probably make this more sophisticated
    ...     d += f.read(diff).replace(b'\x0d\x0a', b'') #\r\n should be bytes b'\x0d\x0a'
    ...     diff = 4 - len(d)
    >>> 
    >>> s = struct.unpack("i", d)
    

    这应该让您了解它的工作原理。这种方法可能会弄乱数据的字节对齐方式。

    如果您确实在 d 打印中看到 "\n",请尝试 .replace(b"\n", b"")

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多