一、文件常用操作
#1. 打开文件的模式有(默认为文本模式): r ,只读模式【默认模式,文件必须存在,不存在则抛出异常】 w,只写模式【不可读;不存在则创建;存在则清空内容】 a, 之追加写模式【不可读;不存在则创建;存在则只追加内容】 #2. 对于非文本文件,我们只能使用b模式,"b"表示以字节的方式操作(而所有文件也都是以字节的形式存储的,使用这种模式无需考虑文本文件的字符编码、图片文件的jgp格式、视频文件的avi格式) rb wb ab 注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码 #3. 了解部分 "+" 表示可以同时读写某个文件 r+, 读写【可读,可写】 w+,写读【可读,可写】 a+, 写读【可读,可写】 x, 只写模式【不可读;不存在则创建,存在则报错】 x+ ,写读【可读,可写】 xb
#掌握 f.read() #读取所有内容,光标移动到文件末尾 f.readline() #读取一行内容,光标移动到第二行首部 f.readlines() #读取每一行内容,存放于列表中 f.write('1111 222 ') #针对文本模式的写,需要自己写换行符 f.write('1111 222 '.encode('utf-8')) #针对b模式的写,需要自己写换行符 f.writelines(['333 ','444 ']) #文件模式 f.writelines([bytes('333 ',encoding='utf-8'),'444 '.encode('utf-8')]) #b模式 #了解 f.readable() #文件是否可读 f.writable() #文件是否可读 f.closed #文件是否关闭 f.encoding #如果文件打开模式为b,则没有该属性 f.flush() #立刻将文件内容从内存刷到硬盘 f.name
1.1、读模式
with open('myx.txt','r',encoding='utf-8') as f: #open函数默认是读默认,所以r可以省略,但是为了规范最好写清楚已哪种方式打开 print(f.read())
1.2、写模式
with open('xie.txt','w',encoding='utf-8') as f: #文件已写模式打开 f.write('123 ') f.write('456 ') f.writelines(['a ', 'b ', 'c '])#写多行 print(f.read())#由于模式之间不兼容,如果只以写模式打开文件,进行读操作会报错 #io.UnsupportedOperation: not readable
1.3、追加模式
with open('xie.txt','a',encoding='utf-8') as f: #和写模式不同,已追加模式打开文件,不会覆盖原文件内容,只会在文件后面进行添加,如果以w模式打开,会将文件原有内容全部清空,重新编写 f.write('789 ')#对于写与追加模式,都可以进行write操作 f.write('aaa ') print(f.read())#追加模式也同样不能进行读操作 #io.UnsupportedOperation: not readable
总结:
文件打开最常用三种模式为读、写、追加。默认为open函数以读模式方式工作,在读模式中可以读取文件内容,写与追加模式均可以对文件进行修改,不同的是,读模式打开文件后,会将原有文件内容清空,添加新内容,而追加模式不会清空原有内容,会在文件最后添加新的需要追加的内容,至于如何在将r、w和a模式进行结合操作,会在修改文件时进行介绍
二、读模式的相关操作
2.1、read操作
with open('myx.txt','r',encoding='utf-8') as f: print(f.read())#read操作会一次性将文件全部内容读取到内存中 print('--------我是分隔符----------') print(f.read())# 由于文件指针的存在,当一次性读取文件到内存后如果不进行指针回退操作前再次读取,会返回空值,表示该内容上一次已经读取完毕,本次读取没有内容显示
2.2、readline操作
with open('myx.txt','r',encoding='utf-8') as f: print(f.readline())#与read操作一次性读取不同,readline操作每次只会读取一行内容存储到内存中,readline方法可以针对每行内容进行操作 print('--------我是分隔符----------') ##输出:作词:甘世佳 作曲:李荣浩
2.3、readlines操作
with open('myx.txt','r',encoding='utf-8') as f: data=f.readlines()#区别于read于readline操作,readlines操作也是一次性读取,不同的是它会将读取的内容放入到一个列表中,这样后续可以操作列表的方式对该文件内容进行需要的操作 print(type(data))#<class 'list'>
2.4、正确的文件读取方式
#方式一、将文件一次性通过readlines方法读到内存中,然后对其进行操作,该方法适合小文件,如果大文件会由于空间过大,导致打开文件速度过慢,不推荐该方式 with open('myx.txt','r',encoding='utf-8') as f: for index,line in enumerate(f.readlines()): print(index,line,end='')#end=''去掉空行 ''' 输出: 0 作词:甘世佳 作曲:李荣浩 1 演唱:薛之谦 2 如果世界漆黑 其实我很美 3 在爱情里面进退 最多被消费 4 不管同样的是非 5 又怎么不对 无所谓 6 如果像你一样 总有人谄媚 7 围绕着我的卑微 也许能消退 8 其实我并不在意 有很多机会 9 像巨人一样的无畏 10 放纵我心里的鬼 11 可是我不配 12 丑八怪 能否别把灯打开 13 我要的爱 出没在漆黑一片的舞台 14 丑八怪 在这暧昧的时代 15 我的存在 像意外 16 有人用一滴泪 会红颜祸水 17 有人丢掉称谓 什么也不会 18 只要你足够虚伪 19 就不怕魔鬼 对不对 20 如果剧本写好 谁比谁高贵 21 我只能沉默以对 美丽本无罪 22 当欲望开始贪杯 有更多机会 23 像尘埃一样的无畏 24 化成灰谁认得谁管他配不配 25 丑八怪 能否别把灯打开 26 我要的爱 出没在漆黑一片的舞台 27 丑八怪 在这暧昧的时代 28 我的存在 不意外 29 丑八怪 其实见多就不怪 30 放肆去high 用力踩 31 那不堪一击的洁白 32 丑八怪 这是我们的时代 33 我不存在 才意外 ''' #第二种方法,data已经变味迭代器而不是列表就没有下标操作,此时会对每行读到内存后进行操作,然后再释放内存,再进行下一行操作,节省内存,推荐该方式操作 with open('myx.txt','r',encoding='utf-8') as f: for line in f: print(line,end='') ''' 输出 作词:甘世佳 作曲:李荣浩 演唱:薛之谦 如果世界漆黑 其实我很美 在爱情里面进退 最多被消费 不管同样的是非 又怎么不对 无所谓 如果像你一样 总有人谄媚 围绕着我的卑微 也许能消退 其实我并不在意 有很多机会 像巨人一样的无畏 放纵我心里的鬼 可是我不配 丑八怪 能否别把灯打开 我要的爱 出没在漆黑一片的舞台 丑八怪 在这暧昧的时代 我的存在 像意外 有人用一滴泪 会红颜祸水 有人丢掉称谓 什么也不会 只要你足够虚伪 就不怕魔鬼 对不对 如果剧本写好 谁比谁高贵 我只能沉默以对 美丽本无罪 当欲望开始贪杯 有更多机会 像尘埃一样的无畏 化成灰谁认得谁管他配不配 丑八怪 能否别把灯打开 我要的爱 出没在漆黑一片的舞台 丑八怪 在这暧昧的时代 我的存在 不意外 丑八怪 其实见多就不怪 放肆去high 用力踩 那不堪一击的洁白 丑八怪 这是我们的时代 我不存在 才意外 '''
2.5、内容替换
屏幕输出上的内容替换
# with open('myx.txt','r',encoding='utf-8') as f: # for index,line in enumerate(f.readlines()): # if index == 9 : # print('--------------------') # print(index,line,end='') with open('myx.txt','r',encoding='utf-8') as f: count = 0 for line in f: if count == 10 : print('----------------------') count+=1 continue print(line,end='') count+=1 ''' 输出: 作词:甘世佳 作曲:李荣浩 演唱:薛之谦 如果世界漆黑 其实我很美 在爱情里面进退 最多被消费 不管同样的是非 又怎么不对 无所谓 如果像你一样 总有人谄媚 围绕着我的卑微 也许能消退 其实我并不在意 有很多机会 像巨人一样的无畏 ---------------------- 第十行被替换了 可是我不配 丑八怪 能否别把灯打开 我要的爱 出没在漆黑一片的舞台 丑八怪 在这暧昧的时代 我的存在 像意外 有人用一滴泪 会红颜祸水 有人丢掉称谓 什么也不会 只要你足够虚伪 就不怕魔鬼 对不对 如果剧本写好 谁比谁高贵 我只能沉默以对 美丽本无罪 当欲望开始贪杯 有更多机会 像尘埃一样的无畏 化成灰谁认得谁管他配不配 丑八怪 能否别把灯打开 我要的爱 出没在漆黑一片的舞台 丑八怪 在这暧昧的时代 我的存在 不意外 丑八怪 其实见多就不怪 放肆去high 用力踩 那不堪一击的洁白 丑八怪 这是我们的时代 我不存在 才意外 '''
针对文件里的内容修改,因为文件内容没有修改这么一说,那么只能是同时打开两个文件,一个读取文件内容,然后写入到新的文件里,再进行重命名
需求,将文件里的alex替换成sb
old.txt
alex hahahah woca le alex alex qunimeide alex feile feile 1111 22222 3333333
######适用于小文件的操作方法 import os with open('old.txt','r',encoding='utf-8') as read_f, open('.old.txt.swap','w',encoding='utf-8') as write_f: msg=read_f.read() # print(msg,type(msg)) msg=msg.replace('alex','SB') # print(msg) write_f.write(msg) os.remove('old.txt') os.rename('.old.txt.swap','old.txt') ########如果文件内容过大,使用下面的操作方法 import os with open('old.txt', 'r', encoding='utf-8') as read_f, open('.old.txt.swap', 'w', encoding='utf-8') as write_f: for line in read_f: if 'SB' in line: line = line.replace('SB', 'alex') write_f.write(line) os.remove('old.txt') os.rename('.old.txt.swap', 'old.txt')
2.6、tell方法与seek方法介绍
with open('myx.txt', 'r', encoding='utf-8') as f: print(f.tell())#tell方法可以只是当前文件指针所在位置,初始为0 print(f.read(10)) #按照索引读取内容 0 到10 print(f.tell())#当读取完毕后再次查看文件指针位置 print(f.read())#读取剩余的全部文件 print(f.tell())#读取此时文件指针位置 print(f.read())#由于文件全部读取完毕,再次读取只能返回空值 print(f.seek(0))#将文件指针置为初始位置 print(f.tell()) print(f.read(23)) print(f.tell())#当读取文件后再次通过tell方法获取文件指针所在位置 ''' 输出 0 作词:甘世佳 作曲: 28 李荣浩 演唱:薛之谦 如果世界漆黑 其实我很美 在爱情里面进退 最多被消费 不管同样的是非 又怎么不对 无所谓 如果像你一样 总有人谄媚 围绕着我的卑微 也许能消退 其实我并不在意 有很多机会 像巨人一样的无畏 放纵我心里的鬼 可是我不配 丑八怪 能否别把灯打开 我要的爱 出没在漆黑一片的舞台 丑八怪 在这暧昧的时代 我的存在 像意外 有人用一滴泪 会红颜祸水 有人丢掉称谓 什么也不会 只要你足够虚伪 就不怕魔鬼 对不对 如果剧本写好 谁比谁高贵 我只能沉默以对 美丽本无罪 当欲望开始贪杯 有更多机会 像尘埃一样的无畏 化成灰谁认得谁管他配不配 丑八怪 能否别把灯打开 我要的爱 出没在漆黑一片的舞台 丑八怪 在这暧昧的时代 我的存在 不意外 丑八怪 其实见多就不怪 放肆去high 用力踩 那不堪一击的洁白 丑八怪 这是我们的时代 我不存在 才意外 1073 0 0 作词:甘世佳 作曲:李荣浩 演唱:薛之谦 如果 65 '''
三、文件的其他操作
3.1、encoding:打印文件编码
>>> data.encoding 'utf-8'
3.2、 fino()返回文件句柄所在操作系统的编码 基本不使用操作
3.3、isatty()该文件是否是一个终端设备,linux系统中可以用来判断是否是一个tty文件
3.4、name打印文件名称
>>> data.name 'yesterday.txt'
3.5、seekable() 是否可以移动指针
>>> data.seekable() True
3.6、flush()刷新操作:
如果以写模式打开文件,写完后不一定立即写入磁盘,如果此时突然断电可能没有及时写入进文件,所以可以通过flush方法刷新进磁盘
例子:可以在安装程序时,打印进度条
import time,sys for i in range(50): sys.stdout.write('#') sys.stdout.flush() #将#号实时刷新到屏幕上来 time.sleep(0.1)
3.7、closed 判断文件是否关闭
>>> data.closed False >>> data.close() >>> data.closed True
3.8、 truncate()如果不写入任何东西就是清空文件
data.truncate(10)会只保留10个字节,其余的会删除,同时truncate自带文件指针,无论通过seek移到任何位置,truncate都会按照初始位置来删除与保留
四、修改文件
修改文件分为两种模式:
1、将文件全部读入内存中,然后修改,该方式典型代表就是vim程序
2、将文件按照行模式读,然后每行操作完毕后再放入新文件,这种方式节约内存占用,类似与sed与awk操作
对于文件操作,除了典型r/w/a方式外还有其他操作,下面来简要介绍这几种更常用操作:
4.1、r+ 读写操作
表示又能读又能写,这个表示以读与追加模式开始,如果写,会将写的内容放入最后
>>> data = open('test1.txt','r+',encoding='utf-8') #以读写模式打开文件 >>> data.readline() #对文件进行读操作 '往日重现 ' >>> data.readline() '当我年轻的时候 ' >>> data.readline() '听着收音机 ' >>> data.readline() '等待着我最喜爱的歌 ' >>> data.write('-------aaaaaaaaaa---------') #对该文件进行写操作 >>> data.readline() '当它播放时我独自跟唱 ' >>> data.readline() '' >>> data.seek(0) >>> data.read() #在重新载入文件进行读写会发现,追加的内容会放在最后 '往日重现 当我年轻的时候 听着收音机 等待着我最喜爱的歌 当它播放时我独自跟唱 -------aaaaaaaaaa---------'
4.2、w+写读模式
创建新文件,输入内容,然后读取文件指针所在位置,在回退,再输入,会发现插入的内容,仍然在最后而不是通过seek调转
>>> data = open('test1.txt','w+',encoding='utf-8')#以w+模式打开 >>> data.write('a-------1 ') >>> data.write('a-------2 ') >>> data.write('a-------3 ') >>> data.write('a-------4 ') #输入内容 >>> data.seek(10) #跳转到第一行 >>> data.readline() #读取第二行 'a-------2 ' >>> data.tell() >>> data.write('a-------5 ') #插入新语句,理论上应该插入到第三行 >>> data.seek(0) >>> data.read() 'a-------1 a-------2 a-------3 a-------4 a-------5 ' #通过读取发现仍然是插入到最后一行,证明通过seek移动文件指针也没法改变w+的文件输入顺序
4.3、a+追加读模式
在追加的过程中可以进行读
>>> data = open('test1.txt','a+',encoding='utf-8') >>> data.read() '' >>> data.tell() >>> data.seek(0) >>> >>> >>> data.write('a----------6 ')#将指针挪到开头后进行追加写操作 >>> data.seek(0) >>> data.read() #重新读取文件发现,追加写仍然按照原有顺序进行添加 'a-------1 a-------2 a-------3 a-------4 a-------5 a----------6 '
五、拷贝图片
针对图片,视频文件,其它文件,都使用rb的方式打开,wb模式写入
with open('test.jpg','rb') as read_f,open('test2.jpg','wb') as write_f: # write_f.write(read_f.read()) for line in read_f: write_f.write(line)
六、二进制文件
针对二进制文件有两种方式,rb与wb,其中两种情况下使用rb:
1、网络传输,socket传输时只能使用二进制格式编码
2、视频文件打开,也必须使用二进制格式打开
七、with语句
为了避免打开文件后忘记关闭,可以通过with来管理上下文,即:
>>> with open('tes2.txt','w') as f:f.write('nnnnn ') ... 6
如此方式,当with代码执行完毕后,内部会自动关闭并释放文件所在内存,同时也可以同时打开多个文件
with open('tes2.txt','w') as f, open('test3.txt','w') as f2:#两个文件之间用‘,’来分割 f.write('nnn ') f2.write('mmmm ')