python的io模块

open函数是一个工厂函数。根据传入的变量,open函数会进行文件的开启、文件对象的创建与设定,然后返回文件对象。我们来看一下指定不同变量时,open函数具体为我们返回了什么类型的文件对象呢:

>>> open('Documents/me.txt')
<_io.TextIOWrapper name='Documents/me.txt' mode='r' encoding='cp936'>
>>> open('Documents/me.txt','rb')
<_io.BufferedReader name='Documents/me.txt'>
>>> open('Documents/me.txt','rb',buffering = 0)
<_io.FileIO name='Documents/me.txt' mode='rb' closefd=True>

Python的IO大致分为三个类型:文本IO(Text IO)、二进制IO(Binary IO)和原始IO(Raw IO)。而上面的TextIOWrapper、BufferedReader、FileIO恰好就是上述三种类型的代表者。

我们通过一张图了解一下io模块中类的继承关系:

python的io模块

接下来我们就可以手动建立文件对象了。

原始IO是无缓冲(Buffer)的低阶字节流操作。如果想以最基本的二进制方式读取文件,就可以直接创建一个FileIO对象。

>>> import io
>>> with io.FileIO('Documents/me.txt') as fin:
	print(fin.read())

b'\xd1\xa7\xbb\xe1\xcb\xbc\xbf\xbc\xa3\xac\xb0\xae\xc9\xcf\xb1\xe0\xb3\xcc\xa1\xa3\r\n\r\n\r\n'

 化名为fin的FileIO对象会逐字节读取文件的内容。FileIO支持的操作模式包括r\w\x\a, 默认是r。由于是面向字节的,所以不存在区分b还是t这样的额外说明。

为了提升FileIO的效率,可以为其加上缓存:

>>> import io
>>> with io.BufferedReader(io.FileIO('Documents/me.txt')) as fin:
	print(fin.read())

b'\xd1\xa7\xbb\xe1\xcb\xbc\xbf\xbc\xa3\xac\xb0\xae\xc9\xcf\xb1\xe0\xb3\xcc\xa1\xa3\r\n\r\n\r\n'

BufferedReader以及BufferedWriter的作用就是一个包裹器,包裹RawIOBase实例。典型的装饰者模式,提升文件的读取效率。

TextIOWrapper也是一个包裹器,包裹BufferedIOBase实例,在缓存式读取二进制内容的基础上,通过指定的字符集,在二进制与字符之间进行转化:

>>> import io
>>> with io.TextIOWrapper(io.BufferedReader(io.FileIO('Documents/me.txt')),'utf8') as fin:
	print(fin.read())

	
学会思考,爱上编程。

如果数据的读取来源或写入目的地并不是磁盘文件,而是内存中的某个对象,那么可以使用BytesIO和StringIO,与文件对象相似的API在内存中对数据进行操作,效率会大大提升。

BytesIO是BufferedIOBase的子类,可以直接构造实例(空的),或者指定一个初始的bytes类型对象,基于该对象进行实例创建。有了BytesIO实例,就可以进行数据的写入和读取了:

import io

bio = io.BytesIO(b'hello, python')
print(bio.read())
bio.seek(6)
bio.write(b'Kitty:)')
print(bio.getvalue())

运行结果:

b'hello, python'
b'hello,Kitty:)'

在对BytesIO实例操作完毕后,通常使用getvalue函数获取全部数据。

BytesIO是基于字节,StringIO就是基于字符的。StringIO是TextIOBase的子类,与BytesIO类似,对StringIO的操作完毕后,也使用getvalue函数获取全部数据。

import io

sio = io.StringIO()
sio.write('hello, python')
sio.write(' and ')
sio.write('Kitty:)')
print(sio.getvalue())

运行结果:

hello, python and Kitty:)

本文参考了林信良编写的《Python编程技术手册》第8章内容,有删改。

上一篇:如何将 Mac 文档文件夹和桌面与 iCloud 同步?


下一篇:git 拉取指定目录