如何在Python中打开和呈现原始二进制数据



这似乎是一种应该有很多重复和大量答案的问题,但我的搜索只导致沮丧和没有可用的解决方案。

在Python(最好是3.x)中,我想知道如何打开任意类型的文件,读取存储在磁盘上的字节,并在对其进行任何编码之前以最'本机','原始','原始'的形式呈现这些字节。

如果文件作为00010100 10000100 ...流存储在磁盘上,那么这就是我想在屏幕上显示的内容。

这类问题通常会引出"你为什么想知道"one_answers"用例是什么"的回答。我很好奇,那是我的用例。

在您将此标记为重复之前,请确保您心中的答案确实回答了问题(而不仅仅是讨论编码等)。谢谢你!

编辑前三个答案后:

感谢到目前为止的三位响应者,特别是J.F. Sebastian的深入讨论。从上面所说的看来,我的问题归结为如何将文件中的字节物理地记录到磁盘上,以及如何读取和显示它们。在这一点上,在Python中似乎不可能获得原始形式的字节视图,但它们有各种表示形式;整数,十六进制值,ascii等。由于这件事还没有解决,我将把这个问题留给更多的人来回答。

如果你不介意字节:

with open('yourfile', 'rb') as fobj:
    raw_bytes = fobj.read()
    print(raw_bytes)

如果你真的想要二进制:

with open('yourfile', 'rb') as fobj:
    raw_bytes = fobj.read()
    print(' '.join(map(lambda x: '{:08b}'.format(x), raw_bytes)))

'rb'模式允许您从Python文件中读取原始二进制数据:

with open(filename, 'rb') as file:
    raw_binary_data = file.read()

type(raw_binary_data) == bytesbytes是Python中不可变的字节序列。

不要混淆字节和它们的文本表示:print(raw_binary_data)会显示数据的文本表示,例如,一个字节127(基数为10:十进制),你可以用
表示bin(127) == '0b1111111'(基数2:二进制)或hex(127) == '0x7f'(基数16:十六进制)显示为b'x7f'(打印7个ascii字符)。来自可打印ascii范围的字节被表示为相应的ascii字符,例如,b'x41'显示为b'A' (65 == 0x41 == 0b1000001)。

0x7f字节不存储为7位ascii二进制数字1111111,不存储为2位ascii十六进制数字7F,不存储为3位文字十进制数字127b'x7f'是字节的文本表示形式,可用于在Python源代码中指定它(您也不会在磁盘上找到七个ascii字符的b'x7f')。下面的代码将一个单个字节写入磁盘:

with open('output.bin', 'wb') as file:
    file.write(b'x7f')

必须使用某种字符来表示字节,它们是什么?

操作系统接口(访问磁盘等硬件的方式)是根据字节定义的,例如,POSIX read(2)也就是说,字节在这里是一个基本单位:你可以直接读/写字节——你不需要任何中间表示。看看理查德·费曼吧。为什么。

字节是如何表示的物理是在操作系统驱动程序和硬件之间的——它可能是任何东西——你不需要担心它:它隐藏在统一的操作系统接口后面。请参阅数据是如何在硬盘驱动器中进行物理写入、读取和存储的?

你可以在Python中直接调用os.read(),但你不需要它;file.read()为您完成(Python 3文件对象直接在POSIX接口上实现)。Python 2 I/O使用C studio库,而C studio库又使用OS接口来实现其功能)。

正如您所指出的,这取决于操作系统驱动程序和硬件来确定字节是如何写入的,但Python解释器随后将能够读取它们。它在读取什么东西,那是什么?它不是读取磁盘上粒子的磁性方向,对吧?它正在读取一些符号,我想要访问它。

正在读取字节。硬盘是一台小型计算机,因此有趣的事情可能会发生,但它不会改变,它一直是字节(就"符号"或软件而言)。

《CODE》一书《计算机硬件和软件的隐藏语言》非常温和地介绍了信息是如何在计算机中表示的——"字节"这个词直到第180页才被定义。要了解计算机中使用的抽象层次,"从NAND到俄罗斯方块"课程可以提供帮助。

Python 3表示文件数据为bytes。类型基本上是一个从0到255的整数列表,所以是一个字节列表。它们有一些方便的方法(例如解码为字符串),并且它们在打印时与字符串类似。

要获得逐位表示,在打开文件时应该使用b模式。

bin()将帮助您将整数转换为二进制表示。但是,您可能必须去掉前两个字符,并用0 s填充。

with open(filename, 'rb') as my_file:
    my_bytes = my_file.read()
    bin_list = [bin(i)[2:].rjust(8, '0') for i in my_bytes]
    print(' '.join(bin_list))

在浏览了一些文档之后,Python似乎没有提供直接操作其数据的物理存储的接口。

相反,数据存储的处理传递给操作系统。这没有明确说明,但我从它的io模块文档中得到了印象。

如果你有一个存储为0110100001100101011011000110110001101111的文件,你用open()打开它。Python将通过与您的操作系统交互来获取其信息,并最终返回给您一个bytes对象,通过该对象,您可以查看其不同格式的内容(例如带有b前缀或十六进制的文本字符串)。

然而,以这种方式(即纯二进制01)实际存储二进制文件是棘手的,因为大多数程序不支持它。大多数情况下,它们都是间接地完成的:您指定内容的表示形式,要么是x68x65x6cx6cx6f,要么是带有编码的b'hello',然后程序和操作系统完成繁重的工作,并将其放回0110100001100101011011000110110001101111

如果我说错了请纠正我:)

相关内容

  • 没有找到相关文章

最新更新