1、文件处理流程
a.打开文件,得到文件句柄并赋值给一个变量
b.通过句柄对文件进行操作
c.关闭文件
2、文件操作模式
有一个文件:小重山
昨夜寒蛩不住鸣。
惊回千里梦,已三更。
起来独自绕阶行。
人悄悄,帘外月胧明。
白首为功名,旧山松竹老,阻归程。
欲将心事付瑶琴。
知音少,弦断有谁听。
读模式:r
文件不存在会报错
file=open('小重山','r',encoding='utf8') # 把小重山这个文件作为一个对象,'r':表示可读,encoding='utf8':编码转换 data=file.read() # 按字符串个数,取字符串内容,默认为所有,可以为数字,表示取多少个字符,加数字没意义 data=file.readline() # 跟随光标按行取内容,每行的末尾都会有一个换行符 ,也算一个字符,取一行内容 data=file.readlines() # 跟随光标位置开始打印所有行,但是是以列表的形式展现出来,想打印所有,就用 for 循环 data data=file.readable() # 判断文件是否可读 file.close() # 只要有打开文件的方法存在,就加上文件关闭的方法 file.tell() # 打印当前光标的位置,按utf8来,读一个字母为进1,一个中文进3,GBK,中文进2,按字节移动 file.seek(0) # 重设光标的位置,按字节移动,一个中文3个字节,例如:当断点后,可以记录传输的位置,并从断点的位置开始重传
其他方法:
f.fileno() # 返回一个操作令牌:当一个对象被你使用时,你会获得这个对象的操作令牌,这个操作令牌是唯一的,且为整型
f.isatty() # 判断对象是否为终端,返回:True、false
写模式:w
file=open('小重山2','w',encoding='utf8') #当 小重山2 这文件不存在,会自动创建一个,如果里面有内容会清空掉
file.write('hello') file.write('alex') # 结果是不换行:helloalex,换行要加 alex file.writelines(['a','b','c']) # abc file.flush() # 当写一条数据后,不存入内存缓存,而是立马写进磁盘,确保安全,但是会降低性能,flush 当内存缓存满了也会自动写进磁盘 file.close()
import sys,time for i in range(30): sys.stdout.write('*') # 进度条显示 sys.stdout.flush() # 等于 print("*",end='',flush=True) time.sleep(0.2) # 进阶版: import sys import time for i in range(101): s=" %s%% %s"%(i,'#'*i) sys.stdout.write(s) sys.stdout.flush() time.sleep(0.1) # 100% #############################
追加模式:a
file=open('小重山','a',encoding='utf8') # 与写模式不同,不会清空文件内容,而是在文件末尾追加内容,文件不存在会创建 file.write(' hello world ') # 追加内容 file.write('alex') # 追加内容 flush.truncate() # 把光标后面的全部删除,默认不加位置,全删了,括号内加数字表示从头开始截多少个字节 file.close()
读写模式:r+
光标在开始位置,先读文件,读完文件光标在最后位置,再写内容,追加写,写完光标在文件末尾 f=open("小重山",'r+',encoding='utf8') print(f.readlines()) f.write(" 岳飞") f.close() with open('小重山', 'r', encoding='utf8') as r: for line in r: print(line.strip()) ''' 昨夜寒蛩不住鸣。 惊回千里梦,已三更。 起来独自绕阶行。 人悄悄,帘外月胧明。 白首为功名,旧山松竹老,阻归程。 欲将心事付瑶琴。 知音少,弦断有谁听。 岳飞 '''
写读模式:w+
先清空文本内容,在写内容,光标会在写完内容的后面,想读内容,seek 位置(不常用) f=open("小重山2",'w+',encoding='utf8') f.write(" 岳飞") f.seek(0) # 如果要读的话要把光标置0才能读 print(f.readlines()) f.close()
追加读模式:a+
光标始终在末尾,读的时候要调整 seek,文件不存在则新建一个 f = open("小重山", 'a+', encoding='utf8') print(f.tell()) f.seek(0) print(f.readlines()) f.close() ''' 234 [' ', '昨夜寒蛩不住鸣。 ', '惊回千里梦,已三更。 ', '起来独自绕阶行。 ', '人悄悄,帘外月胧明。 ', '白首为功名,旧山松竹老,阻归程。 ', '欲将心事付瑶琴。 ', '知音少,弦断有谁听。 ', ' ', '岳飞'] '''
b 模式:rb、wb、ab
不用在编码,而是直接把硬盘里存储的字节数据拿出来,所以不用 encoding
什么情况会用到:不是给人看的,而是给机器看的,一般用于传输,读出文件,然后直接进行网络传输
with open('a.txt','rb') as f: print(f.read().decode('utf8')) # 需要知道是什么编码的 with open('a.txt','wb') as f: f.write('alex李杰'.encode("utf8")) # 写内容以什么编码写进去 with open('a.txt','ab') as f: f.write('egon爱根'.encode("utf8")) # 写内容以什么编码写进去
问题来了:用 rb 模式就不知道是什么编码,因为是字节码,如果非要知道是什么编码方式,用 chardet 模块帮忙吧
chardet模块需要安装:pip3 install chardet
import chardet f = open('兼职白领学生空姐模特护士联系方式utf8.txt', 'rb') data = f.read() print(data) # 全是你看不懂的字节码 print(chardet.detect(data)) # {'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'} f.close() ''' encoding:编码方式 confidence:自信程度... 99%肯定编码编码方式是正确的 language:语言 ''' # 如果不相信模块的自信,那就自己验证一下 print(data.decode('gbk'))
seek 模式:0 1 2,且 seek 模式是针对字节编码的
seek(offset,from)
offset:偏移量
from:方向
0:表示文件开始位置
1:表示文件当前位置
2:表示文件末尾位置
例子: 文件:test5内容 hello元 with open('test5','rb') as f: # 如果要使用 seek 的模式,必须是 ab、wb、rb 模式 print(f.read(3)) # 默认模式 0 ,从文件开始取3个字节 print('----') f.seek(-3,2) # 模式2,从末尾开始往左选3个字节(一个中文字符) print(f.read().decode('utf8')) # 因为是字节编码,转出来内存要解码成utf8编码的unicode 结果: b'hel' ---- 元
文件内光标移动:
一: read(3):
1. 文件打开方式为文本模式时,代表读取3个字符
2. 文件打开方式为b模式时,代表读取3个字节
二: 其余的文件内光标移动都是以字节为单位如seek,tell,truncate
注意:
1. seek有三种移动方式0,1,2,其中1和2必须在b模式下进行,但无论哪种模式,都是以bytes为单位移动的
seek控制光标的移动,是以文件开头作为参照的。
tell当前光标的位置
2. truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果
3、上下文操作
避免忘记底部加 f.close(),只要退出 with 代码块,会自动 close 对象 with open('小重山','r',encoding='utf8') as f: f.read() # 同时打开多个文件 with open('小重山','r',encoding='utf8') as f_read,open('小重山2','w',encoding='utf8') as f_write: for i in f_read: f_write.write(i)
4、文件修改
占用硬盘方式:一个负责读,一个负责写,写完后删除源文件,把写完后的文件重命名为源文件名
import os with open('小重山', 'r', encoding='utf8') as r, open('小重山.swp', 'w', encoding='utf8') as w: for line in r: if '人悄悄' in line: print('true') line = line.replace('人悄悄', '人茫茫') w.write(line) os.remove('小重山') os.rename('小重山.swp', '小重山')
占用内存方式(不推荐):先把文件全部读取出来赋值变量,在变量里替换内容,把光标置0,清空文件,再写内容
f = open('小重山2', 'r+', encoding='utf8') data = f.read() if '人茫茫' in data: data = data.replace('人茫茫', '人悄悄') f.seek(0) f.truncate() f.write(data) f.close()