簡體   English   中英

關於二進制文件的一般問題

[英]General question about Binary files

我是初學者,我在抓取二進制文件時遇到了麻煩。 當我以二進制模式(在python中)寫入文件時,我只寫正常文本。 關於它沒有任何二進制文件。 我知道我的計算機上的每個文件都是二進制文件,但是我無法區分我用二進制模式寫的文件和音頻,視頻等文件,如果我在文本編輯器中打開它們就會顯示為亂碼。

文件如何顯示為亂碼? 你能舉個像這樣創建的小文件的例子,最好是在python中嗎?

我有一種感覺,我問的是一個非常愚蠢的問題,但我不得不問它。 谷歌搜索並沒有幫助我。

以下是您問題的字面答案:

import struct
with open('gibberish.bin', 'wb') as f:
    f.write(struct.pack('<4d', 3.14159, 42.0, 123.456, 987.654))

這就是將這4個浮點數打包成二進制格式(little-endian IEEE 756 64位浮點數)。

這是(一些)你需要知道的:

以二進制模式讀取和寫入文件不會對您讀取或寫入的數據進行轉換。 在文本模式中,以及與Unicode之間的任何解碼/編碼,您讀取或寫入的數據將根據“文本文件”的平台約定進行轉換。

Unix / Linux / Mac OS X:沒有變化

舊的Mac:行分隔符是\\r \\n ,更改為/從Python標准\\n

Windows:行分隔符是\\r\\n ,更改為/從\\n 另外(鮮為人知的事實),Ctrl-Z aka \\x1a被解釋為文件結束,這是一種從CP/M繼承的約定,它將文件大小記錄為所使用的128字節扇區的數量。

當我以二進制模式(在python中)寫入文件時,我只寫正常文本。

升級到Python 3.x時,您必須更改方法:

>>> f = open(filename, 'wb')
>>> f.write("Hello, world!\n")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: must be bytes or buffer, not str
>>> f.write(b"Hello, world!\n")
14

但你的問題並不是關於二進制文件。 這是關於str

在Python 2.x中, str是一個具有重載含義的字節序列:

  • 非Unicode字符串,或
  • 原始二進制數據(如圖像中的像素)。

如果你打印后者就像前者一樣,你會得到胡言亂語。

Python 3.x通過為二進制數據引入單獨的bytes類型來消除這種雙重含義,將str明確地保留為文本字符串(並使其成為Unicode)。

所謂的“文本”文件只是遵循某些約定的文件:字節通常是所有可能字節的子集,通常是ASCII或Unicode值,並且被組織成帶有“行終止符”的“行”。 標准行終止符因平台而異 - Unix使用\\n ,Mac \\r \\n和Windows \\r\\n - 因此常規的一部分是動態翻譯它們。 這適用於文本文件,但會破壞其他類型的文件,因為聲音文件中的0x0a\\n )字節或其他東西不能很好地轉換為0x0d 0x0a\\r\\n )。 當然,如果你只使用Unix,那就不會出現了。

在Python 3中,所有字符串都是Unicode,並且將文件作為文本打開意味着您必須讀取和寫入Unicode字符串,並且可能指定編碼(默認為UTF-8)。 將文件打開為二進制意味着您必須使用bytes對象,這些對象是8位字節的簡單列表,不會被編碼。

這澄清了什么嗎?

通常在嘗試編碼對象時創建二進制文件。 例如,您可能有一個Person對象,其屬性包括Name,Age,Height。 如果您要將此文件寫為文本以便以后可以回讀,則可能會輸出如下內容:

Name:Ralph
Age:25
Height:5'6"

但是你可以用二進制來更緊湊地表示它。 在二進制文件中,您可能只是一個接一個地輸出名稱,年齡和高度,並且您必須以完全相同的順序讀回它們,因為您不再具有這些分隔符。 在這種情況下,你的字符串必須用Ralph\\0編碼。 \\0是空字符,因此它知道字符串結束的位置。

25可以用文本/ ASCII中的兩個字符表示,但是如果你嘗試並排放置兩個數字,比如25和26,你就會得到2526,你不會知道哪一個結束而下一個結束。 這些數字實際上是整數,由4個字節表示。 當你把文件寫成二進制文件時,你會寫出所有4個字節,即使最左邊的位都是0.這樣它總能確切知道讀取多少。 等等...

這就是為什么“二進制文件”看起來像亂碼,因為他們已經獲得了所有這些額外的信息。

要生成這些文件,您必須像John Machin建議的那樣對數據進行編碼或“打包”。

也許你在二進制文件中發送字符串,你的電腦可以解碼並顯示給你? 嘗試用隨機字節寫一個文件。 或者您可以向我們展示您的代碼,以便我們了解問題。

我建議使用Python的編解碼器模塊來編寫文本文件(它允許您設置相關的字符集/編碼)。 對於編寫二進制文件,請使用標准file()方法。 在Windows上,你可能需要使用'wb'或'rb'來表示二進制模式(在Unix上無關緊要)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM