2013-05-14 47 views
7

我讀到這對Python的教程:(http://docs.python.org/2/tutorial/inputoutput.html#reading-and-writing-filesPython是否對處理二進制文件很危險?

Windows上的Python使文本和二進制文件之間的區別; 當讀取或寫入數據時,文本文件中的行尾字符會自動略微改變 。對文件 的這種後臺修改對於ASCII文本文件來說是很好的,但它會破壞JPEG或EXE文件中的 這樣的二進制數據。在讀取時使用二進制模式並寫入這樣的文件時要非常小心。

我不太明白'文本文件中的行尾字符如何改變'會'損壞二進制數據'。 因爲我覺得二進制數據沒有像行尾那樣的東西。

有人能爲我解釋更多這段文字嗎?這讓我覺得Python不喜歡二進制文件。

+4

它讀取「使用二進制模式時要非常小心**」,而不是「當您使用二進制模式時要非常小心......」。二進制模式是安全的。 – Matthias 2013-05-14 07:02:09

回答

14

你只需要小心在windows上打開文件爲二進制文件(open(filename, "rb"))而不是文本文件。之後,使用這些數據沒有問題。

特別是Windows上的行尾是'\r\n'。如果您以文本文件的形式讀取二進制文件並將其寫回,則會在'\r\n'序列中轉換單個'\n'。如果以二進制文件打開文件(用於讀取和寫入),則存在這樣的問題。

Python能夠處理二進制數據,並且您必須在Windows系統上以任何語言使用這種謹慎,而不僅僅是在Python中(但是Python的開發人員足夠友好來警告您可能的操作系統問題)。在像Linux這樣的行尾是單個字符的系統中,這種區別也存在,但在以二進制數據作爲文本讀取/寫入二進制數據(即沒有用於打開文件的b選項)時不太可能導致問題。

+0

明白了。 Python(和其他一些語言)在使用'r'時處理場景後面的特殊字符(行尾)。所以,使用文本模式來處理二進制文件是錯誤的。 – 2013-05-14 07:59:04

2

我覺得二進制數據沒有類似於行尾的東西。

二進制文件可以有任何可能的字符,包括字符\ n。你不希望Python將二進制文件中的任何字符隱式轉換爲其他內容。 Python不知道它正在讀取一個二進制文件,除非你這麼說。當python讀取文本文件時,它會自動將任何\ n字符轉換爲操作系統的換行符,在Windows上它是\ r \ n。

這是事情在所有計算機編程語言中的工作方式。

另一種考慮它的方式是:文件只是一長串字節(8位)。一個字節只是一個整數。一個字節可以是任何整數。如果一個字節恰好是整數10,那也是字符\ n的ascii碼。如果文件中的字節表示二進制數據,則不希望Python在10中讀取並將其轉換爲兩個字節:13和10.通常,當您讀取二進制數據時,您需要讀取前兩個字節代表一個數字,然後是代表另一個數字的下一個4個字節,等等。顯然,如果python突然將其中一個字節轉換爲兩個字節,那將導致兩個問題:1)它改變了數據,2)所有的數據邊界將會搞砸。

一個例子:假設文件的第一個字節應該代表狗的體重,並且該字節的值是10.然後下一個字節應該表示狗的年齡,並且它的值是1.如果Python轉換10,這是\ n個ASCII碼,兩個字節:10和13,那麼你會看數據蟒蛇手,如:

當你提取第二個字節爲狗的年齡,你得到13 - 不是1.

我們經常說一個文件包含'字符',但這是明顯錯誤的。計算機不能存儲字符;他們只能存儲數字。所以文件只是很長的一系列數字。如果你告訴python將這些數字作爲代表字符的ascii代碼處理,那麼python會爲你提供文本。

1

我想Python手冊中的「略有改動」意味着將Unix行尾字符轉換爲Windows行尾字符。因爲這隻在Windows中完成,所以Unix和Linux沒有這個麻煩。