Python笔记-IO编程
IO在计算机中是指input和output(数据输入与输出),涉及到数据交换(磁盘、网络)的地方就需要IO接口。
输入流input stream是指数据从外面(磁盘、网络服务器)流入内存;输出流output stream是指数据从内存流到外面去。
由于cpu与内存的运算速度远高于外设速度,存在严重的速度不匹配问题,这时候有两种IO方式:同步IO、异步IO。
同步IO是指cpu暂停将要执行的后续代码,等待IO执行的结果;异步IO是指cpu不需要IO执行的结果,可以执行其他代码。
好比你去麦当劳点餐,你说“来个汉堡”,服务员告诉你,对不起,汉堡要现做,需要等5分钟,于是你站在收银台前面等了5分钟,拿到汉堡再去逛商场,这是同步IO。
你说“来个汉堡”,服务员告诉你,汉堡需要等5分钟,你可以先去逛商场,等做好了,我们再通知你,这样你可以立刻去干别的事情(逛商场),这是异步IO。
很明显,使用异步IO来编写程序性能会远远高于同步IO,但是异步IO的缺点是编程模型复杂。
想想看,你得知道什么时候通知你“汉堡做好了”,而通知你的方法也各不相同。如果是服务员跑过来找到你,这是回调模式,如果服务员发短信通知你,你就得不停地检查手机,这是轮询模式。总之,异步IO的复杂度远远高于同步IO。
1、文件读写
文本文件
要以读文件的模式打开一个文件对象,使用Python内置的open()
函数,传入文件名和标示符:
try: f=open('E:/t.txt','r') print(f.read()) finally: if f: f.close() print('文件读操作成功')
但是每次都这么写实在太繁琐,所以,Python引入了with
语句来自动帮我们调用close()
方法:
with open('E:/t.txt','r') as f: print(f.read())
read()#一次性读取所有内容(适合小文件) read(size)#每次读取指定字节文件 readline()#每次读取一行文件 readlines()# 一次性读取所有文件内容,并返回list
with open('E:/t.txt','r') as f: for line in f.readlines(): print(line.strip())#把末尾的/n删掉
二进制文件
前面讲的默认都是读取文本文件,并且是UTF-8编码的文本文件。要读取二进制文件,比如图片、视频等等,用'rb'
模式打开文件即可:
with open('E:/t.png','rb') as f: print(f.read(50))
字符编码
要读取非UTF-8编码的文本文件,需要给open()
函数传入encoding
参数,例如,读取GBK编码的文件:
>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk') >>> f.read() '测试'
遇到有些编码不规范的文件,你可能会遇到UnicodeDecodeError
,因为在文本文件中可能夹杂了一些非法编码的字符。遇到这种情况,open()
函数还接收一个errors
参数,表示如果遇到编码错误后如何处理。最简单的方式是直接忽略:
>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk', errors='ignore')
写文件
利用python函数批量生成文件
for x in range(5): with open('F:/'+str(x)+'.docx','w') as f: f.write('')
如果在已存在的文件内容末尾追加内用,open()函数的第二个参数为'a',append
with open('E:/测试文本.txt','a') as f: f.write('\n我是追加的内容,调用的是append()函数')
2、StringIO、BytesIO
StringIO
很多时候,数据读写不一定是文件,也可以在内存中读写。
StringIO顾名思义就是在内存中读写str。
要把str写入StringIO,我们需要先创建一个StringIO,然后,像文件一样写入即可:
>>> from io import StringIO >>> f = StringIO() >>> f.write('hello') 5 >>> f.write(' ') 1 >>> f.write('world!') 6 >>> print(f.getvalue()) hello world!
要读取StringIO,可以用一个str初始化StringIO,然后,像读文件一样读取
from io import StringIO f=StringIO('Hello!\nHi!\nGoodbye!') while True: s=f.readline() if s=='': break print(s)
BytesIO
StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO。
BytesIO实现了在内存中读写bytes,我们创建一个BytesIO,然后写入一些bytes:
StringIO和BytesIO是在内存中操作str和bytes的方法,使得和读写文件具有一致的接口。
3、操作文件和目录
操作文件和目录
操作文件和目录的函数一部分放在os
模块中,一部分放在os.path
模块中,这一点要注意一下。查看、创建和删除目录可以这么调用:
# 查看当前目录的绝对路径: >>> os.path.abspath('.') '/Users/michael' # 在某个目录下创建一个新目录,首先把新目录的完整路径表示出来: >>> os.path.join('/Users/michael', 'testdir') '/Users/michael/testdir' # 然后创建一个目录: >>> os.mkdir('/Users/michael/testdir') # 删掉一个目录: >>> os.rmdir('/Users/michael/testdir')
文件操作使用下面的函数。假定当前目录下有一个test.txt
文件
# 对文件重命名: >>> os.rename('test.txt', 'test.py') # 删掉文件: >>> os.remove('test.py')
os模块不提供复制文件,但是shutil
模块提供了copyfile()
的函数
4、序列化