这似乎是应该有很多重复和大量答案的问题类型,但我的搜索只会导致沮丧和没有可用的解决方案。
在Python(最好是3.x)中,我想知道如何打开任意类型的文件,读取存储在磁盘上的字节,并将这些字节显示在最常用的' native&# 39;,'原创',' raw'表单,在对它们进行任何编码之前。
如果文件作为00010100 10000100 ...
的流存储在磁盘上,那么我希望在屏幕上显示该文件。
这类问题通常会引起回应,“你为什么要知道?”以及'用例'。我很好奇,这是我的用例。
在将此标记为重复之前,请确保您所考虑的答案确实回答了问题(而不仅仅是讨论编码等)。谢谢!
在第一次三次答复后编辑:
感谢三位响应者到目前为止,特别是对J.F. Sebastian进行了扩展讨论。从所说的内容看来,我的问题归结为文件中的字节如何物理记录到磁盘以及如何读取和呈现它们。在这一点上,在Python中看起来不可能获得原始形式的字节视图,但它们可用于各种表示形式;整数,十六进制值,ascii等。由于事情尚未解决,我将保持问题开放以获得更多输入。
答案 0 :(得分:4)
'rb'
模式使您能够从Python中读取文件中的原始二进制数据:
with open(filename, 'rb') as file:
raw_binary_data = file.read()
type(raw_binary_data) == bytes
。 bytes
是Python中不可变的字节序列。
不要混淆字节及其文本表示:print(raw_binary_data)
会显示数据的文本表示形式,例如,您可以表示为<的字节127
(基数10:十进制)登记/>
bin(127) == '0b1111111'
(基数2:二进制)或hex(127) == '0x7f'
(基数16:十六进制)显示为b'\x7f'
(打印七个ascii字符)。来自可打印ascii范围的字节表示为相应的ascii字符,例如,b'\x41'
显示为b'A'
(65 == 0x41 == 0b1000001
)。
0x7f
字节不作为七个ascii二进制数字1111111
存储在磁盘上,它不存储为两个ascii十六进制数字:7F
,它不存储为三个文字十进制数字127
。 b'\x7f'
是字节的文本表示,可用于在Python源代码中指定它(您也不会在磁盘上找到文字七个ascii字符b'\x7f'
)。
此代码将单个字节写入磁盘:
with open('output.bin', 'wb') as file:
file.write(b'\x7f')
必须使用某种字符来表示字节,它们是什么?
OS接口(访问磁盘等硬件的方式)是以字节为单位定义的,例如POSIX read(2),即字节是这里的基本单位:你可以直接读/写字节 - 你不要&# 39;不需要任何中间代表。观看Richard Feynman. Why.
字节如何表示物理是在OS驱动程序和硬件之间 - 它可能是任何东西 - 您不必担心它:它隐藏在统一的OS界面之后。见How is data physically written, read and stored inside hard drives?
您可以直接在Python中调用os.read()
,但您不需要它; file.read()
为您做到了(Python 3文件对象直接在POSIX接口上实现.Python 2 I / O使用C stdio库,而后者又使用OS接口来实现其功能)。
正如您所指出的,由操作系统驱动程序和硬件决定如何写入字节,但Python解释器可以读取它们。所以它正在阅读一些东西 - 那是什么?它没有读取磁盘上颗粒的磁性取向,是吗?它正在阅读象征性的东西,我希望能够访问它。
它的读取字节数。硬盘是一台小型计算机,因此interesting things可能会发生,但它不会一直改变它的字节(至于&#34;符号&#34;或软件)。
The book "CODE The Hidden Language of Computer Hardware and Software"非常温和地介绍了如何在计算机中表示信息 - 单词&#34; byte&#34;直到第180页才定义。要查看计算机中使用的抽象级别the course "From NAND to Tetris" can help。
答案 1 :(得分: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)))
答案 2 :(得分: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))
答案 3 :(得分:0)
浏览了一些文档之后,Python似乎没有提供直接操作其数据物理存储的接口。
相反,数据存储的处理将传递给操作系统。这没有明确说明,但是我从其io module文档中得到了印象。
如果您有一个文件存储为0110100001100101011011000110110001101111
,并用open()
打开了它。 Python将通过与您的操作系统进行交互来获取其信息,并最终返回一个bytes
对象,您可以通过该对象以不同的格式(例如,带有b
前缀或十六进制的文本字符串)查看其内容。
但是,以这种方式实际存储二进制文件(即纯粹以二进制0
和1
的形式存储二进制文件很棘手,因为大多数程序都不支持它。在大多数情况下,它们都是通过间接操作来完成的:您可以使用\x68\x65\x6c\x6c\x6f
或b'hello'
来指定内容的表示形式,并使用一种编码,然后程序和操作系统会进行繁重的工作,它返回到0110100001100101011011000110110001101111
。
如果我错了,请纠正我:)