引用
普通部分
rb
主要是为了读取二进制文件而创立的字段,因为二进制字段中很有可能有1A
(\x)这个编码,但是这个在普通文件中表示的EOF,即文档结束符,所以如果使用r
读取二进制文件就会造成将1A
当成文件结束符,导致这个字符后面的部分没有读取上,出现文档读取不全的现象。
如果我们读取人工书写的数据那么就使用r
,如果我们读取非人工书写的数据那么我们就是使用rb
,图片就是一种非常典型的非人工书写数据。
with open('photo.jpg', 'rb') as f:
jpgdata = f.read()
高阶部分
- 如果使用的mode是
r
,那么你就要非常清楚,这个数据是用什么编码来书写的,读取的时候也要用对应的编码,否则就有可能由于解码错误,导致乱码。因为对于计算机来说,只有字符(byte),而没有(str),而将byte翻译成str的方式就是依据encoding的方式而定的,所以我们可以通过设置encoding字段来指定解码格式,utf-8是现在的主流编码方式,如果没有指定encoding 的方式那么根据python版本的不同会有不同的解码方式,Python3中是utf-8,而python2中是ascii。
>>> # Python2
>>> import sys
>>> sys.getdefaultencoding()
'ascii'
>>> # Python3
>>> import sys
>>> sys.getdefaultencoding()
'utf-8'
- open函数返回的是一个句柄,是将操作系统所持有的句柄交给open函数,当然我们需要对文件操作结束以后调用close函数,将关闭这个句柄,因为每个程序打开文件数量是有上限的,只有打开之后进行关闭,才不会触及这个上限,但是有个问题就是如果在open函数和close函数之间程序运行发生了错误,那么就会导致句柄没有关闭,这不是我们希望看到了,所以为了保证是否有错误发生都要关闭句柄,我们可以使用with语句,句柄只有在with语句内部是可以使用的,如果在with语句外面(比如出错时候的traceback)句柄是自动关闭的,所以就解决了这一个痛点。
小例子
b,u,r
因为在window系统里面 回车是用\r\n表示的,Linux系统离水面回车使用\n表示的,说明mode是rb
的时候,写的时候系统写进文件的二进制编码是什么就按什么方式呈现出来,字符串前面是b表示这个是一个byte类型的对象,只不过输出台将这个转换成了人能读懂的形式。
f=open('C:\\Users\\MapReducer\\Desktop\\text.txt','rb')
for line in f:
print(line)
>>
#
b'name: James\r\n'
b'age: 20\r\n'
b'---\r\n'
b'name: Lily\r\n'
b'age: 19'
因为文件中每一行的末尾有一个回车,print函数也会自己在输出一个回车,所以输出两个空格,说明了如果mode是r
的话,人写进去的是什么形式的读出来就是什么形式的,不管在什么系统下回车的编码方式是什么。
f=open('C:\\Users\\MapReducer\\Desktop\\text.txt','r')
for line in f:
print(line)
>>
name: James
age: 20
---
name: Lily
age: 19