9

我在 Python 教程上读到了这个:(http://docs.python.org/2/tutorial/inputoutput.html#reading-and-writing-files

Windows 上的 Python 区分了文本文件和二进制文件;读取或写入数据时,文本文件中的行尾字符会自动稍作更改。这种对文件数据的幕后修改适用于 ASCII 文本文件,但它会破坏 JPEG 或 EXE 文件中的二进制数据。在读写此类文件时要非常小心使用二进制模式。

我不太明白“更改文本文件中的行尾字符”将如何“损坏二进制数据”。因为我觉得二进制数据没有行尾之类的东西。

有人可以为我解释更多这一段吗?这让我觉得 Python 不欢迎二进制文件。

4

3 回答 3

16

您只需要注意在 Windows 上将文件作为二进制 ( open(filename, "rb")) 而不是文本文件打开。之后使用数据就没有问题了。

特别是 Windows 上的行尾是'\r\n'. 如果您将二进制文件作为文本文件读取并将其写回,则单个文件将按顺序'\n'转换。'\r\n'如果您将文件作为二进制文件打开(用于读取和写入),则不会出现此类问题。

Python 能够处理二进制数据,您必须在 Windows 系统上的任何语言中都小心谨慎,而不仅仅是在 Python 中(但 Python 的开发人员非常友好,可以警告您可能出现的操作系统问题)。在像 Linux 这样行尾是单个字符的系统中,这种区别也存在,但在以文本形式读取/写入二进制数据时不太可能导致问题(即没有b打开文件的选项)。

于 2013-05-14T06:00:01.087 回答
3

我觉得二进制数据没有行尾之类的东西。

二进制文件中可以包含任何可能的字符,包括字符 \n。您不希望 python 将二进制文件中的任何字符隐式转换为其他字符。除非你告诉它,否则 Python 不知道它正在读取二进制文件。当 python 读取文本文件时,它会自动将任何 \n 字符转换为操作系统的换行符,在 Windows 上是 \r\n。

这就是所有计算机编程语言的工作方式。

另一种思考方式是:文件只是一长串字节(8 位)。一个字节只是一个整数。一个字节可以是任何整数。如果一个字节恰好是整数 10,那也是字符 \n 的 ascii 码。如果文件中的字节表示二进制数据,您不希望 Python 读取 10 并将其转换为两个字节:13 和 10。通常当您读取二进制数据时,您希望读取前 2 个字节代表一个数字,然后接下来的 4 个字节代表另一个数字,等等。显然,如果 python 突然将一个字节转换为两个字节,那将导致两个问题:1)它改变了数据,2)你所有的数据边界会搞砸的。

举个例子:假设一个文件的第一个字节应该代表一只狗的体重,这个字节的值是 10。那么下一个字节应该代表狗的年龄,它的值是 1。如果 Python 将 10 转换为是 \n 的 ascii 代码,转换为两个字节:10 和 13,然后 python 手中的数据将如下所示:

10 13 1

当您提取狗年龄的第二个字节时,您会得到 13,而不是 1。

我们经常说文件包含“字符”,但这显然是错误的。计算机不能存储字符;他们只能存储数字。所以文件只是一长串数字。如果你告诉 python 将这些数字视为代表字符的 ascii 代码,那么 python 会给你文本。

于 2013-05-14T05:59:47.783 回答
1

我想 Python 手册中的“稍微改变”是指将 Unix 行尾字符转换为 Windows 行尾字符。因为这只能在 Windows 中完成,所以 Unix 和 Linux 没有这个麻烦。

于 2013-05-14T06:05:13.507 回答