文件操作基本流程
打开文件(指定文件路径、文件编码方式、打开文件的模式),得到文件句柄并赋值给一个变量;
通过句柄对文件进行操作;
open打开文件是通过操作系统来打开文件,在windows中默认使用的编码方式为gbk,而python默认编码方式为utf8,所有打开文件时如果不指定encoding='utf8',是会出现乱码的。
关闭文件(文件关闭了才会将内容从缓冲区写到磁盘,如果没有写f.close(),python会自动把该文件关闭但是前提是运行的程序已经执行完毕)
现有文件如下:使用pycharm创建文件,该文件默认会以utf8编码方式。如果在操作系统中创建该文件,则文件的编码方式为gb2312(写文件时要注意软件默认使用的编码方式)
1 昨夜寒蛩不住鸣。
2 惊回千里梦,已三更。
3 起来独自绕阶行。
4 人悄悄,帘外月胧明。
5 白首为功名,旧山松竹老,阻归程。
6 欲将心事付瑶琴。
7 知音少,弦断有谁听。
对上述文件进行操作:
1 f = open('小重山','r',encoding='utf8') #打开文件,读模式
2 data=f.read()#获取文件内容 f.read()是将文件中的所有内存读出,如果文件过大,这种不建议使用,建议使用循环的方式,每次读取固定大小,如:data=f.read(1024),即一次读取1024个字符。(在read中无论是英文字母还是中文都表示一个字符)
3 print(data)
4 f.close() #关闭文件
=open('小重山',encoding='utf8')。即文件是以什么编码方式存储的,就要以对应的编码方式来打开此文件。
文件打开模式
只读
r:以字符串(unicode)方式读
f = open('小重山', 'r', encoding='utf8')
data = f.read()
print(data,type(data)) # <class 'str'>
f.close()
#输出
昨夜寒蛩不住鸣。
惊回千里梦,已三更。
起来独自绕阶行。
人悄悄,帘外月胧明。
白首为功名,旧山松竹老,阻归程。
欲将心事付瑶琴。
知音少,弦断有谁听。 <class 'str'>
注意:文件以bytes编码方式打开,当在read时,隐含执行了将bytes转化成str的操作即以字符串方式读文件
rb:以字节串(bytes)方式读文件,无需指定编码方式。适用读非文字的文件。
f = open('小重山', 'rb')
data = f.read()
print(data)
f.close()
# b'\xe6\x98\xa8\xe5\xa4\x9c\xe5\xaf\x92\xe8\x9b\xa9\xe4\xb8\x8d\xe4\xbd\x8f\xe9\xb8\xa3\xe3\x80\x82\r\n\xe6\x83\x8a\xe5\x9b\x9e\xe5\x8d\x83\xe9\x87\x8c\xe6\xa2\xa6\xef\xbc\x8c\xe5\xb7\xb2\xe4\xb8\x89\xe6\x9b\xb4\xe3\x80\x82\r\n\xe8\xb5\xb7\xe6\x9d\xa5\xe7\x8b\xac\xe8\x87\xaa\xe7\xbb\x95\xe9\x98\xb6\xe8\xa1\x8c\xe3\x80\x82\r\n\xe4\xba\xba\xe6\x82\x84\xe6\x82\x84\xef\xbc\x8c\xe5\xb8\x98\xe5\xa4\x96\xe6\x9c\x88\xe8\x83\xa7\xe6\x98\x8e\xe3\x80\x82\r\n\xe7\x99\xbd\xe9\xa6\x96\xe4\xb8\xba\xe5\x8a\x9f\xe5\x90\x8d\xef\xbc\x8c\xe6\x97\xa7\xe5\xb1\xb1\xe6\x9d\xbe\xe7\xab\xb9\xe8\x80\x81\xef\xbc\x8c\xe9\x98\xbb\xe5\xbd\x92\xe7\xa8\x8b\xe3\x80\x82\r\n\xe6\xac\xb2\xe5\xb0\x86\xe5\xbf\x83\xe4\xba\x8b\xe4\xbb\x98\xe7\x91\xb6\xe7\x90\xb4\xe3\x80\x82\r\n\xe7\x9f\xa5\xe9\x9f\xb3\xe5\xb0\x91\xef\xbc\x8c\xe5\xbc\xa6\xe6\x96\xad\xe6\x9c\x89\xe8\xb0\x81\xe5\x90\xac\xe3\x80\x82'
只写
w:如果文件不存在会创建新文件,然后再向文件中添加内容;如果文件存在先将原文件中的内容清空,再向文件中添加新内容。 以字符串方式写。
f = open('log', 'w', encoding='utf8')
f.write("骑兵步兵")
f.close()
#log文件中的内容
骑兵步兵
wb:以byte方式写。需要注意的是,当你以wb方式向文件中写入内容时,要查看对应的文件默认是以什么编码方式,也要以相应的编码方式向文件中写内容(在pycharm中pycharm创建的文件默认使用的编码方式是utf-8,所以这里就以utf-8的编码方式向pycharm创建的文件中写内容,使用gbk的编码方式写则就会出现乱码)。
f = open('log1', 'wb')
f.write("骑兵步兵".encode('utf8'))
f.close()
追加
a:以字符串方式追加,从文件最后位置开始写(即只能写)
f = open('log', 'a', encoding='utf8')
f.write("炮兵")
f.close()
#log原文件中的内容:
骑兵步兵
#追加后的文件内容
骑兵步兵炮兵
ab:以bytes方式追加,从文件最后位置开始写。需要注意的是,当你以wb方式向文件中写入内容时,要查看对应的文件默认是以什么编码方式,也要以相应的编码方式向文件中写内容(在pycharm中pycharm创建的文件默认使用的编码方式是utf-8,所以这里就以utf-8的编码方式向pycharm创建的文件中写内容,使用gbk的编码方式写则就会出现乱码)。
f = open('log', 'ab')
f.write("海军".encode('utf8'))
f.close()
#log原文件中的内容
骑兵步兵炮兵
#追加后log文件中的内容
骑兵步兵炮兵海军
读写
r+:先将原文件读出,此时光标定位在文件最后,则写的内容放在文件的最后即先读后写(r+:可读可写)
# log中文件内容为:python9
f = open('log', 'r+', encoding='utf8')
print(f.read()) # python9
f.write('大猛,小猛')
f.close()
# 此时log文件中的内容为:
# python9大猛,小猛
f.read()之后,光标位于python9中的9之后,所以后面write会在9之后开始写。
读写只能读一次:
# log中文件内容为:python9
f = open('log', 'r+', encoding='utf8')
print(f.read()) # python9
f.write('大猛,小猛')
f.write('大猛,小猛')
print(f.read())
f.close()
# 此时log文件中的内容为:
# python9大猛,小猛大猛,小猛
先写再读:
# log中文件内容为:python9 f = open('log', 'r+', encoding='utf8') f.write('aaa') print(f.read()) # hon9 f.close() # 此时log文件中的内容为: # aaahon9
f.write()之后,光标位于aaa的a之后,后续的读就从a之后开始读。
r+b:以byte方式读写
# log中文件内容为:python9
f = open('log', 'r+b')
print(f.read()) # b'python9'
f.write('大猛,小猛'.encode('utf8'))
f.close()
# 此时log文件中的内容为:
# python9大猛,小猛
w+:先清空文件,再写读(w+:可写可读)
# log中文件内容为:python9
f = open('log', 'w+',encoding='utf8')
f.write('abc')
f.seek(0) # 此时光标位于c之后,f.read()会输出空,将光定位到0位置才能读出写入的内容
print(f.read()) # abc
f.close()
# 此时log文件中的内容为:
# abc
a+:光标默认在最后的位置。即写在文件最后开始写,读在文件最后开始读。(a+:可追加可读)
# log中文件内容为:python9
f = open('log', 'a+', encoding='utf8')
f.write('abc')
print(f.read()) # 这里输出为空
f.close()
# 此时log文件中的内容为:
# python9abc
# 如果要想输出文件中的内容,需要做光标定位
f = open('log', 'a+', encoding='utf8')
f.write('abc')
f.seek(0)
print(f.read()) # python9abc
f.close()
总结:不管是读还是写,光标都会进行移动。读或写都是从光标位置开始读或写。追加都是从文件最后开始写。
文件操作方法
1. 读出文件的前几个字符,read读出来的都是字符
# log中文件内容为:python9
f = open('小重山', 'r', encoding='utf8')
content = f.read(3) #即读文件的前3个字符
print(content) # 昨夜寒
f.close()
2. 移动光标到指定的位置,按照字节来定位光标位置;作用:比如断点续传
f = open('小重山', 'r', encoding='utf8')
f.seek(3)
content = f.read()
print(content)
f.close()
#输出
夜寒蛩不住鸣。 # utf中一个中文字符3个字节,这里移动光标“昨”无法输出
惊回千里梦,已三更。
起来独自绕阶行。
人悄悄,帘外月胧明。
白首为功名,旧山松竹老,阻归程。
欲将心事付瑶琴。
知音少,弦断有谁听。
3. tell :取出当前光标所处的位置
f=open('小重山','r',encoding='utf8') print(f.tell()) print(f.read(10)) print(f.tell()) #输出: 0 昨夜寒蛩不住鸣。 惊 29 #tell中英文一个字符,中文3个字符(前提是使用utf8编码)
4.readline():一行一行读取
f=open('小重山','r',encoding='utf8')
print(f.readline())
print(f.readline())
输出:
岳飞寒蛩不住鸣。
惊回千里梦,已三更。
5.readlines():每一行当成列表中的一个元素,添加到列表中
f=open('小重山','r',encoding='utf8')
print(f.readlines())
#输出
['岳飞寒蛩不住鸣。\n', '惊回千里梦,已三更。\n', '起来独自绕阶行。\n', '人悄悄,帘外月胧明。\n', '白首为功名,旧山松竹老,阻归程。\n', '欲将心事付瑶琴。\n', '知音少,弦断有谁听。']
6.一行一行的读取文件中所有内容
1 f = open('小重山','r',encoding='utf8')
2 for i in f.readlines():
3 print(i.strip()) # strip 方法可以去回车
4
5 输出:
6 昨夜寒蛩不住鸣。
7 惊回千里梦,已三更。
8 起来独自绕阶行。
9 人悄悄,帘外月胧明。
10 白首为功名,旧山松竹老,阻归程。
11 欲将心事付瑶琴。
12 知音少,弦断有谁听。
例子:在第6行添加iiiii:
f = open('小重山','r',encoding='utf8')
data=f.readlines()
f.close()
number=0
for i in data:
number+=1
if number == 6:
i = ''.join([i.strip(), 'iiiii'])
print(i.strip())
#输出:
昨夜寒蛩不住鸣。
惊回千里梦,已三更。
起来独自绕阶行。
人悄悄,帘外月胧明。
白首为功名,旧山松竹老,阻归程。
欲将心事付瑶琴。iiiii
知音少,弦断有谁听。
优化:
1 ##########对于大数据文件,要用以下方式(the best way): 2 f = open('小重山','r',encoding='utf8') 3 number=0 4 for i in f:#这是for内部将f对象做成一个迭代器,一次只读取一行内容到内存即内存中只有一行数据。 5 number+=1 6 if number == 6: 7 i = ''.join([i.strip(), 'iiiii']) 8 print(i.strip())
7.flush:write是在文件关闭之前统一将内存中的数据写入磁盘,对于安全性要求高的,flush就有用途了,即立刻将内存中的数据写入磁盘,无需等到文件关闭。
进度条例子:
1 import sys,time
2 for i in range(30):
3 sys.stdout.write("*") #sys.stdout 终端输出对象
4 sys.stdout.flush()
5 time.sleep(0.1)
如果没有使用flush,将会在循环结束后统一将30个*一次从终端输出
print的flush:
1 import sys,time
2 for i in range(30):
3 print('*',end='',flush=True) #end='' 不换行
4 time.sleep(0.1)
8.truncate:截断(即删除)数据(注意不能再r模式下)
1 #在w模式下:先清空文件,再写数据,再截断
2 #在a模式下:直接将指定位置后的内容截断
3 f=open('小重山','w',encoding='utf8')
4 f.write('hello world')
5 f.truncate(5)
6 f.close()
#小重山文件中内容为:hello
如何在磁盘修改文件
常规思路:由于磁盘存储机制不能够实现
1 f=open('小重山','r+',encoding='utf8')
2 number=0
3 for line in f:
4 number+=1
5 if number==3:
6 f.write('alex')
r+:写都是在文件最后开始写
只能采取重新创建一个文件的思路:
1 f_read=open('小重山','r',encoding='utf8')
2 f_write = open('小重山2','w',encoding='utf8')
3
4 number=0
5 for line in f_read:
6 number+=1
7 if number==5:
8 line=''.join([line.strip(),'alex\n'])
9 f_write.write(line)
10
11 f_read.close()
12 f_write.close()
文件操作之with操作
为了避免打开文件后忘记关闭,可以通过管理上下文,即:
1 with open('小重山','r',encoding='utf8') as f:
2 print (f.read())
通过该方式,当with代码块执行完毕时,内部会自动关闭并释放文件资源。
在Python 2.7 后,with又支持同时对多个文件的上下文进行管理,即:
with open('log1','r',encoding='utf8') as f_read, open('log2','w',encoding='utf8') as f_write:
for line in f_read:
f_write.write(line)