2013-05-14 40 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没有这个麻烦。