2015-10-15 81 views
1

这似乎是应该有很多重复和大量的答案的问题类型,但我的搜索只导致挫折和没有可用的解决方案。我想知道如何打开一个任意类型的文件,读取存储在磁盘上的字节,并将这些字节显示在他们最“本地的”,“最简单的”原始','原始'形式,在任何编码完成之前。如何在Python中打开和呈现原始二进制数据?

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

这类问题通常引发“你为什么想知道”和“用例是什么”的回答。我很好奇,这是我的用例。

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

编辑后的第三个答案:

得益于三个反应了这一点,特别是对J.F.塞巴斯蒂安的广泛讨论。从所说的话看来,我的问题归结为文件中的字节如何被物理记录到磁盘以及它们如何被读取和呈现。在这一点上,Python似乎不可能获得原始表单中字节的视图,但它们可用于各种表示;整数,十六进制值,ascii等等。由于事情没有解决,我会留下这个问题以获得更多的意见。

+0

正如我所说*显式*在我的答案:Python确实获得原始字节:你可以阅读它们,你可以写它们。如果你的问题如果你调用'file.read(1)',到底发生了什么,那么这是一个不同的问题(答案是:很多事情正在发生 - 不同的操作系统行为不同,不同的文件系统行为不同,硬盘是整个计算机也就是说,你的普通计算机是一个计算机网络 - 只要它不影响结果 - 它并不重要)。 – jfs

回答

1

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)) 
+1

把它转换成一个列表:'list(b'abc')'→'[97,98,99]'。您还可以通过索引'b'abc'[1]'→'98'来访问每个元素。 –

2

如果你罚款字节:

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))) 
3

'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'(打印七个ASCII字符)。来自可打印字符范围的字节表示为相应的ASCII字符,例如,b'\x41'显示为b'A'65 == 0x41 == 0b1000001)。

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

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

某种类型的字符必须被用来代表字节,它们是什么?

操作系统接口(您访问硬件,如磁盘的方式)在字节例如,POSIX read(2)即来定义,该字节是这里的基本单位:您可以直接读取/写入字节 - 你不需要任何中间表示。手表Richard Feynman. Why.

如何字节来表示物理是操作系统驱动程序和硬件之间 - 这可能是任何东西 - 你不必担心它:它被隐藏在统一的OS接口后面。见How is data physically written, read and stored inside hard drives?

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

正如您指出的那样,操作系统驱动程序和硬件需要确定如何写入字节,但Python解释器将能够读取它们。所以它正在读一些东西 - 那是什么?它没有读取磁盘上的颗粒磁性方向​​,是吗?它正在阅读一些象征性的东西,并且我想要访问它。

它是读取字节。硬盘是一台小型计算机,因此可能会发生interesting things,但不会改变它的字节一直向下(就“符号”或软件而言)。

The book "CODE The Hidden Language of Computer Hardware and Software"提供了一个非常温和的引入信息是如何在计算机中表示 - 词“字节”没有定义,直到180页,查看通过电脑,the course "From NAND to Tetris" can help使用抽象水平。

+0

@DhaLee:你是否明白'00000001'是* 8 *个字符,你可能会*解释为基数2系统中的一个数字('0b1(base 2)== 0x1(base 16)== 1(base 10) '),因此它可以表示*'b'\ x01''字节?你知道相同的数字可以用不同的基数表示吗?你知道你不能在一个字节中寻址各个位:按照定义,一个字节是最小的可寻址单元?有些电脑的字节可能多于/少于8位,尽管在这里并不重要。 – jfs

+0

@DhaLee:没有。字节在这里是基本的(它不是Python限制)。观看[我已链接的视频](http://www.youtube.com/watch?v=36GT2zI8lVA)。这可能有助于理解为什么字节不能用其他方式表示。 – jfs

相关问题