IO编程
IO在计算机中指的是Input/Output,也就是输入输出。用到数据交换的地方,都会涉及到IO编程,例如磁盘,网络的数据传输。
在IO编程中,Stream(流) 是一种概念,分为输入流(Input Stream)和输出流(Output Stream)。
一个负责输入,一个负责输出。本例主要讲解磁盘IO操作。
open函数
open(name[.mode[.buffering]])
open函数使用一个文件名作为唯一的强制参数,然后返回一个文件对象。模式(mode)和缓冲区(buffering)参数都是可选的,默认模式是读模式,默认缓冲区是无。
文件模式
model值 功能描述
r 读模式
w 写模式
a 追加模式
b 二进制模式(可添加到其他模式使用)
+ 读/写模式(可添加到其他模式中使用)
model值 | 功能描述 |
---|---|
r | 读模式 |
w | 写模式 |
a | 追加模式 |
b | 二进制模式(可添加到其他模式使用) |
+ | 读/写模式(可添加到其他模式中使用) |
这里的’b’参数,一般处理一些其他类型的文件(二进制文化),比如mp3音乐或者图形等等。那么应该在模式参数中增加 ‘b’
参数 rb 可以用来读取一个二进制文件。
文件缓冲区
open函数第三个可选参数buffering控制着文件的缓冲,如果参数是0, I/O操作就是无缓冲的,直接将数据写道硬盘上;如果参数是1,I/O操作就是由缓冲的,数据先写到内存里,
只有使用flush函数或者close函数才会将数据更新到硬盘;如果参数为大于1的数字则代表缓冲区的大小(单位是字节),-1(或者是任何负数)代表使用默认缓冲区的大小。
文件读取
文件读取主要是分为按字节读取和按行进行读取,经常用的方法 read(),readlines(),close()
open 成功打开文本文件,接下来调用read()方法 最后一步调用close(),关闭对文件的引用。文件使用完毕后必须关闭。
f = open(r'test.txt')
read = f.read()
f.close()
由于文件操作可能会出现IO异常,一旦出现IO异常,后面的close()方法就不会调用,需要使用try…finally
try:
f = open(r'test.txt', 'r')
print(f.read())
finally:
if f:
f.close()
python 提供了一种简单的方法,用with语句来替代 try…finally代码块和close()
with open(r'test.txt', 'r') as f:
print(f.read())
调用read()已将文件内容读到内存,但是如果文件过大,会出现内存不足的问题。对于大文件,可以反复调用read(size)方法,一次最多读取size个字节
如果文件是文本文件,Python提供了更加合理的做法,调用readline()可以每次读取一行内容,调用readlines()一次读取所有内容并按行返回列表。
with open(r'test.txt', 'r')as f:
for line in f.readlines():
print(line.strip())
文件写入
写 和 读文件差不多一致,唯一的区别是调用open方法,传入标识符 w 或者 wb 表示写入文本文件或者写入二进制文件
可以反复调用write()方法写入文件,最后也必须使用close()方法来关闭文件。
使用write()方法的时候,操作系统不是立即将数据写入文件种,而是先写入内存种缓存起来,等到空闲时候再写入文件种。
f = open(r'test.txt', 'w')
f.write('yiqi')
f.close()
操作文件和目录
Python中对文件和目录操作经常用到了os模块和shutil模块。
- os.getcwd():获得当前Python脚本工作的目录路径。
- os.listdir(‘C:\’):返回指定目录下的所有文件和目录名。
- os.remove(‘filepath’):删除一个文件
- os.removedirs(r’fliepath’):删除多个空目录
- os.path.isfile(filepath):检验给出路径是否是一个文件
- os.path.isdir(filepath):检验给出路径是否是一个目录
- os.path.isabs():判断是否是绝对路径
- os.path.exists(filepath):检验路径是否真的存在
- os.path.split(filepath):分离一个路径的目录名和文件名
- os.path.splitext(filepath):分离扩展名
- os.path.dirname(filepath):获取路径名
- os.path.basename(filepath):获取文件名
- os.getenv()和os.putenv():读取和设置环境变量
- os.linesep:给出当前平台使用的行终止符。
- os.name:只是你正在使用的平台
- os.rename(old,new):重命名文件或者目录
- os.makedirs(filepath):创建多级目录
- os.mkdir(filepath):创建单个目录
- os.stat(file):获取文件属性
- os.chmod(file):修改文件权限与时间戳
- os.path.getsize(filepath):获取文件大小
- shutil.copytree(‘olddir’, ‘newdir’):复制文件夹
- shutil.copyfile(‘oldfile’, ‘newfile’):复制文件
序列号操作
程序运行时,所有的变量都是再内存中,例如程序中声明一个对象,再程序运行中对象中一个属性变化,但是程序已结束或者异常中的,程序中的内存变量都会被操作系统进行回收,如果没有把属性变化后的值存储起来,下次运行程序的时候,这个变量会被初始化变化之前的值。
把内存中的变量变化成可存储或可传输的过程,就是序列化。
将内存中的变量序列化之后,可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上,实现程序状态的保存和共享。反过来,把变量内容从序列化的对象重新读取到内存,称为反序列化
Python中提供了cPickle和pickle来实现序列号,效率前者高,功能是一样的。
try:
import cPickle as pickle
except ImportError:
import pickle
pickle实现序列化主要使用的是dumps方法或dump方法
dumps方法可以将任意对象序列化成一个str,然后可以将这个str写入文件进行保存。
dump方法,可以将序列化后的对象直接写入文件中
d = dict(url='index.html', title='首页', conent='首页')
pickle.dumps(d)
f = open(r'dump.txt', 'wb')
pickle.dump(d, f)
f.close()
pickle实现反序列使用的是loads方法或load方法。
把序列化后的文件从磁盘上读取为一个str,然后使用loads方法将这个str反序列化为对象。
或者直接使用load方法将文件直接反序列化为对象。
f = open(r'dump.txt', 'rb')
d = pickle.load(f)
f.close()