2015-10-15 29 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

相關問題