一、初识文件操作
使用python来读写文件是非常简单的操作,我们使用open()函数来打开一个文件, 获取到文件句柄,然后通过文件句柄就可以进行各种各样的操作了。根据打开方式的不同能够执行的操作也会有相应的差异。打开文件的方式: r, w, a, r+, w+, a+, rb, wb, ab, r+b, w+b, a+b 默认使用的是r(只读)模式。
二、读模式— r,rb
#语法
# f = open('文件名',mode ='模式' , encoding = '编码格式') # s = f.read() # f.close() # print(s)
读取一个文本操作,需要定位到目标文件所在的位置.使用相对路径(相对于你当前程序所在的文件夹)
f = open('../week01/666',mode='r',encoding='UTF-8') # '../week01/666'是找到目标文件所在的位置, ../是返回上一层文件夹。 # mode是选择对文件的操作模式。encoding是文件的编码格式 s = f.read() #读取文件 f.close() #关闭句柄 print(s) #输出文件名为’666‘的内容 hello world
rb,读取出来的数据是bytes类型,在rb模式下,不能选择encoding字符集.
f = open('../week01/666', mode='rb') s = f.read() print(s) #打印的是bytes类型, b'hello world'
当一个文件很大时,我们不能把它直接读出来,内存会无法读取,所以可以先读取一部分.
循环读取, 这种方式是组好的. 每次读取一行内容.不会产生内存溢出的问题. readline() 一次读取一行数据, 注意: readline()结尾, 注意每次读取出来的数据都会有一个 所以呢. 需要我们使用strip()方法来去掉 或者空格. readlines()将每一行形成一个元素, 放到一个列表中. 将所有的内容都读取出来. 所以也是容易出现内存崩溃的问题.不推荐使用
f = open('../../123.txt',mode='r',encoding='utf-8')#当文件名有后缀是要带上后缀 for line in f: #句柄可以进行迭代
print(line) #打印出来的每一行之间都有一个空行 f.close() # 北京 # # 上海 # # 广州 # # 深圳 # # 杭州 # # 南京
f = open('../week01/666', mode='r',encoding='utf-8') s = f.read(9) #读取9个字节,就是三个汉字或9个uing问字母 print(s) #hello wor ss = f.read(6) #继续读取是从上一次读取到的位置开始读,而不是从头读 print(ss) #ld
f = open('../../123.txt',mode='r',encoding='utf-8') s1 = f.readline() #一次只能读取一行 s2 = f.readline() s3 = f.readline() s4 = f.readline() print(s1) print(s2) print(s3) print(s4) # 北京 # # 上海 # # 广州 # # 深圳
f = open('../../123.txt',mode='r',encoding='utf-8') s = f.readlines() # 拿到列表 ['北京 ', '上海 ', '广州 ', '深圳 ', '杭州 ', '南京 '] print(s) for s in s: ss = s.strip() # strip() 去掉空格. 还可以去掉换行符 , 制表符 print(ss) # 北京 # 上海 # 广州 # 深圳 # 杭州 # 南京
三、写模式— w
f = open('../tt',mode='w',encoding='utf-8') s = f.write('你好啊') #先清空文本的内容,再添加写入的内容. f.close()
f = open('新建',mode='wb') s = f.write('郑州'.encode('utf-8')) #删除文件以前的内容,存入'郑州' f.close()
四、追加模式— a,ab
在追加模式下,写入的内容会追加在文件的结尾.
f = open('新建',mode='a',encoding='utf-8') s = f.write('郑州') #不删除文件以前的内容,在文件内容末尾加入'郑州' f.close()
f = open('新建',mode='ab') # 不用再写encoding s = f.write('郑州'.encode('utf-8')) #不删除文件以前的内容,在文件内容末尾加入'郑州' f.close()
五、读写模式— r+
对于读写模式.必须是先读.因为默认光标是在开头的.准备读取的.当读完了之后再进行写入.我们以后使用频率最高的模式就是r+
正确操作:
f = open('新建',mode='r+',encoding='utf-8') s = f.read() #先读取文本 print(s) ss = f.write('伦敦') #在文见内容末尾加入'伦敦' f.close()
错误操作:
f = open('新建',mode='r+',encoding='utf-8') s = f.write('伦敦') #在没有进行读操作前,光标默认在最开始,添加的伦敦把北京给覆盖了,覆盖后,光标移到了'伦敦'后面 ss = f.read() #因为光标移到了'伦敦'后面,所以读取就从'伦敦'后面开始读
f.close()
print(ss) #第一行的北京没了
# 上海 # 广州 # 深圳 # 杭州 # 南京
六、写读模式— w+
w+先将所有的内容清空. 然后写入. 最后读取. 但是读取的内容是空的, 不常用
f = open('新建',mode='w+',encoding='utf-8') f.write('伦敦') #删除文件以前的内容,添加'伦敦' s = f.read() #读取内容为空
f.close() print(s)
七、追加写读— a+
a+模式下, 不论先读还是后读. 都是读取不到数据的.
f = open('新建',mode='a+',encoding='utf-8') s = f.write('伦敦') #文件内容末尾添加'伦敦' ss = f.read() print(s)
八、光标—seek()
seek(n) 光标移动到n位置,移动的单位是byte. 所以如果是UTF-8的中文部分要是3的倍数.通常我们使用seek都是移动到开头或者结尾.
移动到开头: seek(0) 移动到结尾: seek(0,2),seek的第二个参数表示的是从哪个位置进⾏行行偏移,默认是0,表示开头,1表示当前位置,2表示结尾.
f = open('../week01/666', mode='r',encoding='utf-8') f.seek(3) #光标移到3个字节(一个中文或3个英文字母) s = f.read() print(s) #lo world f.seek(0) #光标从0开始 ss = f.read() print(ss) #hello world f.seek(0,2) #光标移动末尾 sss = f.read() print(sss) #空
九、文件修改
文件修改: 只能将文件中的内容读取到内存中, 将信息修改完毕, 然后将源文件删除, 将新文件的名字改成老文件的名字.
import os with open('水果',mode='r',encoding='utf-8') as f1, open('水果副本',mode='w',encoding='utf-8') as f2: for c in f1: s = c.replace("果","你") f2.write(s) os.remove('水果') #删除水果文件 os.rename('水果副本','水果') #重命名水果副本
十、补充知识点
1.判断是否可读,可写
with open('../tt',mode='r',encoding='utf-8') as f: print(f.readable()) #判断是否可读 True print(f.writable()) #判断是否可写 False
2.截取.truncate()
with open('../tt',mode='r+',encoding='utf-8') as f: f.seek(6) #光标移动6个字节,两个汉字 s = f.truncate() #不给参数. 从文件头.截取到当前位置 f.close() with open('../tt',mode='r+',encoding='utf-8') as f: f.seek(6) #光标移动6个字节,两个汉字 s = f.truncate(12) #给了参数. 从文件头截取到你给这个参数的位置.与光标位置无关 f.close()