文件操作
文件处理流程
-
打开文件,得到文件句柄并赋值给一个变量
-
通过句柄对文件进行操作
-
关闭文件
读文件
实例一:
f = open(file='E:/python/test/user.txt',mode='r',encoding='utf-8') data = f.read() f.close() # 语法解释 file='E:/python/test/user.txt' # 表示文件路径(可以修改为其他) mode = 'r' # 表示只读 encoding='utf-8' # 表示将硬盘上的0101010按照utf-8的规则去“断句”,再将“断句”后的 # 每一段0101010转换成Unicode的01010101,Unicode对照表中有01010101和字符的对应关系 # 另外需要注意,此处的encoding必须和文件在保存时设置的编码一致,不然“断句”会不准确从而造成乱码 f.read() # 表示读取所有内容,内容是已经转换完毕的字符串 f.close() # 表示关闭文件
实例二:
f = open(file='E:/python/test/user.txt',mode='rb') data = f.read() f.close() # 语法解释 file='E:/python/test/user/txt' # 表示文件路径 mode = 'rb' # 表示只读(可以修改为其他) f.read() # 表示读取所有内容,内容从硬盘上原来以某种编码保存的010101010,即某种编码格式的字节类型 f.close() # 表示关闭文件
实例一与实例二的区别:实例二打开文件时并未指定encoding,这是因为直接以rb模式打开了文件,rb是指二进制模式,数据读取到内存里直接是bytes格式,如果想要内容,还需要手动decode,因此在文件打开阶段,不需要指定编码。
假如不知道要处理的文件是什么编码格式:
import chardet f= open(file='E:/python/test/user.txt',mode='rb') data = f.read() f.close() result = chardet.detect(open(file='E:/python/test/user.txt',mode='rb').read()) print(result) # {'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'}
注意:
-
文件操作时,以“r”或“rb”模式打开,则只能读,无法写入;
-
硬盘上保存的文件都是某种编码的0101010,打开时需要注意:
-
rb,直接读取文件保存时原生的0101010,在Python中用字节类型表示
-
r和encoding,读取硬盘的0101010,并按照encoding指定的编码格式进行断句,再将“断句”后的每一段0101010转换成Unicode的0101010101,在Python中用字符串类型表示
-
循环文件
f = open(file='E:/python/test/user.txt',mode='r',encoding='utf-8') for line in f: print(line) f.close()
写文件
f = open(file='E:/python/test/user.txt',mode='w',encoding='utf-8') f.write('name:路飞') f.close() # 语法解释 file='E:/python/test/user.txt' # 表示文件路径 mode = 'w' # 表示只写 encoding='utf-8' # 将要写入的Unicode字符串编码成utf-8格式 f.write() # 表示写入内容,写入的内容是Unicode字符串格式,内部会根据encoding转换成指定编码的01010101,即字节类型 f.close() # 表示关闭文件
二进制写
f = open(file='E:/python/test/user.txt',mode='wb') f.write('name:路飞') f.close() # 语法解释 file='E:/python/test/user.txt' # 表示文件路径 mode = 'wb' # 表示只以二进制模式写 f.write() # 表示读取所有内容,写入的内容必须字节类型,即某种编码格式的010101010 f.close() # 表示关闭文件
注意:
-
文件操作时,以“w”或“wb”模式打开,则只能写,并且在打开的同时会先将内容清空;
-
写入到硬盘上时,必须是某种编码的0101010,打开时需要注意:
- wb,写入时需要直接传入以某种编码的0101010,即字节类型
-
w和encoding,写入时需要传入Unicode字符串,内部会根据encoding指定的编码将Unicode字符串转换成该编码的0101010101
追加
把内容追加到文件尾部
f = open(file='E:/python/test/user.txt',mode='a',encoding='gbk') f.write('name:路飞') f.close()
注意:
-
文件操作时,以“a”或“ab”模式打开,则只能追加,即在原来内容的尾部追加内容;
-
写入到硬盘上时,必须是某种编码的0101010,打开时需要注意:
- ab,写入时需要直接传入以某种编码的0101010,即字节类型
-
a和encoding,写入时需要传入Unicode字符串,内部会根据encoding指定的编码将Unicode字符串转换成该编码的0101010101
读写
读写模式
f = open(file='E:/python/test/user.txt',mode='r+',encoding='gbk') data = f.read() # 可以读内容 print(data) f.write('name:路飞') # 可以写;(内容追加到了最后面) f.close()
写读模式
f = open(file='E:/python/test/user.txt',mode='w+',encoding='gbk') data = f.read() print(data) f.write('\nname:路飞') f.write('\nname:索隆') f.write('\nname:山治') print(f.read()) f.close()
此时查看文件内容发现,里面只有三条内容,之前的旧内容全没了。事实证明,w+会先把文件清空,再写新内容,相比w模式,只是支持了一个读功能,且还只能读已经写入的新内容....
修改
import os with open('user.txt','r',encoding='utf-8') as old_f,\ open('new_user.txt','w',encoding='utf-8') as new_f: for line in old_f: new_f.write(line) os.rename('new_user.txt','user.txt')
文件操作的其他方法:
-
fileno() # 返回文件句柄在内核中的索引值,以后做IO多路复用时可以用到
-
flush() # 把文件从内存buffer里强制刷新到硬盘
-
readable() # 判断是否可读
-
readline() # 只读一行,遇到\r or \n为止
-
seek() # 把操作文件的光标移到指定位置。 注意:seek的长度是按字节算的,字符编码存每个字符所占的字节长度不一样。 如“路飞”用gbk存是2个字节一个字,用utf-8就是3个字节,因此以gbk打开时,seek(2)就把光标切换到了“路”和“飞”两个字中间。但如果是utf-8,seek(2)会导致,拿到了路这个字的一部分字节,打印的话会报错,因为处理剩下的文本时发现用utf-8处理不了了,因为编码对不上,少了一个字节。
-
seekable() # 判断文件是否可进行seek操作
-
tell() # 返回当前文件操作光标的位置
-
truncate() # 按指定长度截断文件 注意: 指定长度的话,就从文件开头开始截断指定长度,不指定长度的话,就从当前位置到文件尾部的内容全去掉。
-
writable() # 判断文件是否可写