读写文件是最常见的IO操作。Python内置了读写文件的函数,用法和C是兼容的。
读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)。
文件操作流程
1 打开文件,得到文件句柄并赋值给一个变量。
2 通过句柄对文件操作
3 关闭文件
测试文件:
1 他多想是棵小草 2 他多想是棵小草,染绿那荒郊野外 3 他多想是只飞雁,闯翻那滔滔云海 4 哪怕是野火焚烧,哪怕是雷轰电闪 5 也落个逍遥自在,也落个欢心爽快 6 他多想是棵小草,染绿那荒郊野外 7 他多想是只飞雁,闯翻那滔滔云海 8 哪怕是野火焚烧,哪怕是雷轰电闪 9 也落个逍遥自在,也落个欢心爽快 10 蹉跎了岁月,伤透了情怀 11 为什么,为什么,偏有这样的安排?
基本操作
读文档
f= open('banished.txt',encoding="utf-8")#通过open函数打开一个文件,返回文件句柄 print(f.read())#读取文件内容 f.close()#关闭文件
print(f.encoding)#utf-8 查看文件编码。因为打开的方式用的是utf-8
以上为读出来的内容,read()函数会把文件内的内容一次性全部读出来,如果读取两次会有什么效果呢?
f = open('banished.txt','r',encoding="utf-8") data1 = f.read() data2 = f.read() print(data1) print('---------------%s '% data2) f.close()
重新读了一次但是并没有打印内容。原来当我们对文件操作的时候,文件内部会有一个文件指针来定位当前位置,初始位置0按字节内容移动。read()方法会把内容全部读出来并且把文件指针移动到末尾,这个时候在用read()方法在去读内容发现没有内容可以读就返回空。如果有需求确实要重新读取文件,那么可以使用移动文件指针的方法。
查看文件指针位置
tell() 查看当前光标位置
f = open('banished.txt','r',encoding="utf-8")
print(f.tell())#0
print(f.readline())#他多想是棵小草
print(f.tell())#23
调整指针的方法
seek(index) 移动光标到某个位置
f = open('banished.txt','r',encoding="utf-8") print(f.tell())#0 print(f.read(6))#他多想是棵小 print(f.tell())#18 f.seek(0)#0 print(f.tell())#0 print(f.read(6))#他多想是棵小
读取指定内容长度
read(size) 读取指定字节长度的内容
f = open('banished.txt','r',encoding="utf-8") print(f.tell())#0 print(f.read(6))#他多想是棵小 print(f.tell())#18
read()方法会一次性读取全部内容, 如果要读的文档很大,这样很容易撑爆内存。所以,在大对文档读取的时候,每次读取指定长度的内容反复读取比较保险。
一行一行读,内存只保留1行的方法:
f = open('banished.txt','r',encoding="utf-8") for line in f: print(line)
写文档
‘w’ 模式写文件会创建一个文件,文件原来有内容会被覆盖。用这个模式打开后的文件不能用read()方法读文件。
banished1.txt 文档内容
# Author:zhang 他多想是棵小草 他多想是棵小草,染绿那荒郊野外 他多想是只飞雁,闯翻那滔滔云海 哪怕是野火焚烧,哪怕是雷轰电闪 也落个逍遥自在,也落个欢心爽快 他多想是棵小草,染绿那荒郊野外 他多想是只飞雁,闯翻那滔滔云海 哪怕是野火焚烧,哪怕是雷轰电闪 也落个逍遥自在,也落个欢心爽快 蹉跎了岁月,伤透了情怀 为什么,为什么,偏有这样的安排?
f = open('banished1.txt','w',encoding='utf-8') f.write('老西游记配曲') f.close()
执行写操作后
老西游记配曲
读和写一样会偏移文件指针
f = open('banished1.txt','w',encoding='utf-8') f.write('老西游记配曲 ')#内容换行 f.write('很经典的配乐') f.close()
写完后的内容
老西游记配曲 很经典的配乐
‘a’ 文档追加 这个模式不会覆盖原文件。
f = open('banished1.txt','a',encoding='utf-8') f.write(' 许镜清老师作品') f.close()
写完后的内容
老西游记配曲 很经典的配乐 许镜清老师作品
新内容已经追加到最后。
flush() 刷新缓冲区
一般写文件会先把内容加入到缓冲区,然后在从缓冲区加载到磁盘。flush()方法会把缓冲区的内容立即写入到磁盘,不需要被动的等待缓冲区写入。一般情况下,文件关闭后自动刷新缓冲区。
f = open('banished1.txt','w',encoding='utf-8') f.write(' 许镜清老师作品') f.flush()
truncate 内容截断
f = open('banished1.txt','a',encoding='utf-8') f.truncate(10)#截取10个字节,大于10个字节的内容清空,中文字符会有乱码现象 f.flush()
读写
‘r+’ 又能读又能写 写的内容在最后
f = open('banished.txt','r+',encoding='utf-8') print( f.readline()) print( f.readline()) print( f.readline()) f.write('--------------') print( f.read())
写读
'w+' 先创建一个文件,再向文件里面写。
测试先读后写
测试文本
banished2.txt
他多想是棵小草 他多想是棵小草,染绿那荒郊野外 他多想是只飞雁,闯翻那滔滔云海 哪怕是野火焚烧,哪怕是雷轰电闪 也落个逍遥自在,也落个欢心爽快 他多想是棵小草,染绿那荒郊野外 他多想是只飞雁,闯翻那滔滔云海 哪怕是野火焚烧,哪怕是雷轰电闪 也落个逍遥自在,也落个欢心爽快 蹉跎了岁月,伤透了情怀 为什么,为什么,偏有这样的安排?
f = open('banished2.txt','w+',encoding='utf-8') print( f.readline()) print( f.readline()) print( f.readline()) f.write('--------------') print( f.read())
banished2.txt
测试先写后读
f = open('banished2.txt','w+',encoding='utf-8') f.write('-------------- ') f.write('-------------- ') f.write('-------------- ') f.write('-------------- ')#先写4行内容 f.seek(10)#光标移动到第10个字符 print(f.tell())#打印光标位置 print(f.readline())#把这一行读完,光标移动到下一行 f.write('111111111111111 ')#这个时候光标是在第二行,想写入新内容 f.close()
实际还是追加到最后了。3.0已经不允许这么做了。
2.7中打开一个文件对这个文件修改,并不能从中间某个位置追加内容,而是从那个位置开始修改覆盖后面的内容。
读写二进制文件
‘rb’ 读二进制文件
f = open('banished.txt','rb')#二进制格式下没有字符编码 print(f.readline()) print(f.readline())
'wb' 写二进制格式到文件 这里要写入的内容必须是二进制格式的 否则会报错
f = open('banished.txt','wb') f.write('nihao')#写一个字符串格式的内容尝试下 f.close()
内容转成二进制后
f = open('banished2.txt','wb') f.write('nihao'.encode())#默认用程序的字符集 f.close()
并没有报错,看下输出结果。
内容已写入。
文件修改
一行一行的循环读,查找要修改的字符串,修改替换。
f = open('banished.txt','r',encoding='utf-8') f_new = open('banished1.txt','w',encoding='utf-8') for line in f: if '飞雁' in line: line = line.replace('飞雁','大雁') f_new.write(line) f.close() f_new.close()
with语句
避免打开文件忘记关闭,with 可以自动关闭文件。
with open('banished.txt','r',encoding='utf-8') as f: for line in f: print(line)
在2.7之后,wirh支持同时对多个文件的操作
with open('banished.txt','r',encoding='utf-8') as f,open('banished1.txt','r',encoding='utf-8') as d: pass
进度条小游戏
import sys,time for i in range(50): sys.stdout.write('#') sys.stdout.flush() time.sleep(0.1)
参考文档:文件读写 --- 廖雪峰Python3