初识文件操作
基本要素:
1、文件路径:文件在哪
绝对路径:从根目录下一直找直到找到文件
相对路径:同一个文件夹下,文件名字
2、编码方式:gbk,utf-8.。。
文件以什么编码存储的,就要以什么编码打开
3、操作方式:读、写、追加、读写、写读。。。。
对文件进行操作:
1、打开文件,产生文件句柄
2、对文件句柄进行你想要的操作
3、关闭文件句柄
python处理文件
读文件:
1 f = open(file='D:\Python3\Luffycity\兼职',mode='r',encoding='gbk') 2 data = f.read() 3 f.close()
# 语法解释 file='D:\Python3\Luffycity\兼职' # 表示文件路径 mode='r' # 表示只读 encoding='gbk' # 表示将硬盘上的010101按照gbk的规则去“断句”, # 再将“断句”后的每一段010101转换成Unicode的010101,Unicode对照表中有010101和字符的对应关系 # 此处的encoding必须和文件在保存时设置的编码一致,否则会造成乱码 f.read() # 表示读取所有内容,内容是已经转换完毕的字符串 f.close() # 表示关闭文件
rb模式读文件:
rb是二进制模式,数据读到内存里直接是bytes格式,如果想看内容,需要手动decode,因此在文件打开阶段,不需要指定编码
1 f = open(file='D:\Python3\Luffycity\兼职',mode='rb') 2 data = f.read() 3 f.close()
# 语法解释 file='D:\Python3\Luffycity\兼职' # 表示文件路径 mode='rb' # 表示只读 f.read() # 表示读取所有内容,内容是硬盘上原来以某种编码保存的010101,即:某种编码格式的字节类型 f.close() # 表示关闭文件
1 f = open('兼职',mode='rb') 2 data = f.read() 3 f.close() 4 5 print(data) # 打印bytes类型 b'\xd0\xd5\xc3\xfb\t ....' 6 s = data.decode('gbk') 7 print(s) # 打印字符串 姓名 地区 身高
如果不知道文件编码,可使用chardet模块判断编码方式
1 import chardet 2 3 result = chardet.detect(open('兼职',mode='rb').read()) 4 print(result) 5 6 # 结果 7 # {'confidence': 0.99, 'language': 'Chinese', 'encoding': 'GB2312'}
注意:
文件操作时,以‘r’或‘rb’模式打开,则只能读,无法写入
硬盘上保存的文件都是某种编码的0101011,打开时需注意:
rb,直接读取文件保存时原生的0101010,在python中用字节类型表示
r 和 encoding,读取硬盘的0101011,并按照encoding指定的编码格式进行断句,再将断句后的每一段0101010转换成Unicode的01001010,在python中用字符串类型表示
循环文件
1 f = open('兼职',mode='r',encoding='gbk') 2 3 for line in f: 4 print(line) 5 6 f.close()
写文件
1 f = open('兼职',mode='w',encoding='utf-8') 2 f.write('北大本科 50 微信:1234567') 3 f.close()
二进制写
1 f = open('兼职2',mode='wb') 2 f.write('北大本科 50 微信:1234567'.encode('utf-8')) 3 f.close()
注意:
文件操作时,以‘w’或‘wb’模式打开,则只能写,并且在打开的同时会先将内容清空
写入到硬盘上时,必须是某种编码的010101,打开时需注意:
wb,写入时需要直接传入以某种方式编码的010101,即:字节类型
w 和 encoding,写入时需要传入Unicode字符串,内部会根据encoding指定的编码将Unicode字符串转换为该编码的0010011
追加
把内容追加到文件尾部
1 f = open('兼职',mode='a',encoding='utf-8') 2 f.write('\n shanshan 北京 167 47 13333333333') 3 f.close()
1 f = open('兼职2',mode='ab') 2 f.write('\nshanshan 北京 167 47 13333333333'.encode('gbk')) 3 f.close()
注意:
文件操作时,以‘a’或‘ab’模式打开,则只能追加,即:在原来的内容的尾部追加内容
写入到硬盘上时,必须是某种编码的0101010,打开时需要注意:
ab,写入时需要直接传入以某种编码的010110,即:字节类型
a 和 encoding,写入时需要传入Unicode字符串,内部会根据encoding指定的编码将Unicode字符串转换为该编码的0100100
读写模式
1 f = open('兼职',mode='r+',encoding='utf-8') 2 data = f.read() 3 print(data) 4 f.write('\n黑姑娘 北京 171 51 13333322222') 5 f.close()
f.read() 读原内容
f.write() 把要写的内容追加到最后面
写读模式
1 f = open('兼职 - 副本', mode='w+', encoding='utf-8') 2 data = f.read() 3 print(data) 4 f.write('\nnewline 1 哈哈') 5 f.write('\nnewline 2 哈哈') 6 7 print("content", f.read()) 8 9 f.close()
# 输出结果 # 这里是一个空行,是print(data)的结果 content # 并没有读到什么东西,原因是 写完之后光标在最后,f.read()从光标开始读。。。。
w+会先把文件清空,再写新内容,相比w模式,之支持一个读功能,还要手动移光标才能读新写的内容,没什么用。。。。
文件操作的其他功能
1 f = open('兼职 - 副本','r',encoding='utf-8') 2 3 data = f.fileno() # 返回文件句柄在内核中的索引值,IO多路复用时用到 4 print(data) # 3 5 6 data = f.flush() # 把文件从内存buffer里强制刷新到硬盘 返回None 7 print(data) 8 9 print(f.readable()) # 判断是否可读 10 print(f.writable()) # 判断文件是否可写 11 12 data = f.readline() # 只读一行,遇到\r或\n为止 13 print(data) 14 15 print(f.seekable()) # 判断文件是否可以进行seek操作 16 f.seek(7) # 把操作文件的光标移到指定位置 按字节算 17 data = f.read() # 如果文件是中文,且光标移动到字符中间,会报错 18 print(f.tell()) # 返回当前文件操作光标位置 19 print(data) 20 21 f.close()
1 # def truncate() # 只能在可写的条件下,对原文件进行截取,按字节去截取 2 3 f = open('截取','w+',encoding='utf-8') 4 data = f.truncate(6) 5 6 f.close()
修改文件
当把文件存到硬盘上时,就在硬盘上划出一块空间,存数据,下次打开这个文件,seek到某个位置,每修改一个字,就是把原来的覆盖掉,如果要插入,是不可能的,因为后面的数据在硬盘上是不会整体向后移的
想要修改文件,
一个是把所有数据读到内存中,进行修改,然后再存到硬盘上;
另一个就是边读边改,即:打开旧文件时,同时生成一个新文件,边从旧文件一行一行读,边往新文件一行一行写,遇到需要修改的就修改后再写到新文件,这样不占内存,占硬盘
占硬盘方式
1 f_name = '兼职白领' 2 f_new_name = '%s.new' % f_name 3 4 old_str = '乔亦菲' 5 new_str = '[乔亦菲 Yifei Qiao]' 6 7 f = open(f_name,'r',encoding='utf-8') 8 f_new = open(f_new_name,'w',encoding='utf-8') 9 10 for line in f: 11 # print(line) 12 if old_str in line: 13 new_line = line.replace(old_str,new_str) 14 else: 15 new_line = line 16 17 f_new.write(new_line) 18 19 f.close() 20 f_new.close()
若要新文件覆盖原文件,使用os模块
1 import os 2 3 f_name = '兼职白领' 4 f_new_name = '%s.new' % f_name 5 old_str = '乔亦菲' 6 new_str = '[乔亦菲 Yifei Qiao]' 7 8 f = open(f_name,'r',encoding='utf-8') 9 f_new = open(f_new_name,'w',encoding='utf-8') 10 for line in f: 11 # print(line) 12 if old_str in line: 13 new_line = line.replace(old_str,new_str) 14 else: 15 new_line = line 16 f_new.write(new_line) 17 18 f.close() 19 f_new.close() 20 21 os.replace(f_new_name,f_name) # 把新文件名字改成原文件的名字,就把之前的文件覆盖掉了,Linux使用os.rename
占内存
1 f_name = '兼职白领' 2 3 old_str = '乔亦菲' 4 new_str = '[乔亦菲 Yifei Qiao]' 5 6 f = open(f_name,'r+',encoding='utf-8') 7 8 data = f.read() 9 new_data = data.replace(old_str,new_str) 10 11 f.seek(0) 12 f.write(new_data) 13 14 f.close()