为了更好地说明接下来的文件修改操作,我们有必要先来学习下文件操作的常用方法。
一、文件处理中的常用方法
#!/usr/bin/env python3 #-*- coding:utf-8 -*- # write by congcong # flush() 把文件从内存强制刷新到硬盘 f = open(‘w_flush.txt‘,mode=‘r+‘) f.write("这是强制刷新到硬盘的文件!") f.flush() print("查看文件:",f.read()) # f.close() # readable() 判断是否可读 print(f.readable()) #输出:True f1 = open("w_flush.txt",mode=‘w‘) #文件的写操作 f1.write(‘判断文件是否可读!‘) f1.flush() print(f1.readable()) # 输出:False (表明写操作时文件也是不可读的) # readline() 输出一行,碰到\r 或者 \n结束 f = open(‘w_flush.txt‘,mode=‘a‘,encoding=‘gbk‘) f.write(‘我是第一行!‘) f.write(‘\n我是第二行!‘) f = open(‘w_flush.txt‘,mode=‘r‘,encoding=‘gbk‘) print(f.readline())#输出:我是第一行! # tell() 返回光标当前位置,以字节为计算单位 print(f.tell()) #输出 ; 14,因为编码为 gbk ,gbk每个中文字符占两个字节,所以此时光标位于第一行末尾 # seek() 将光标移到指定字节位置,以字节为计数单位 print(f.seek(2)) #输出:2 print(f.readline()) # 输出;是第一行! print(f.seek(4)) #输出:4 print(f.readline()) #输出:第一行 # seekable() 判断文件能否seek,linux中使用(一切皆文件) # read() 括号内指定长度时,就从当前位置开始读几个字符;括号内没有指定长度时,就读全部文件,以字符为单位 print(f.tell()) print(f.seek(0)) print(f.read(2)) #输出:我是 # truncate() 按指定长度截断文件,括号内指定长度时,就从文件开头开始截断指定长度;不指定长度时,从当前位置到尾部的内容全部去掉 #此方法必须是在写模式下使用 f = open(‘w_flush.txt‘,‘r+‘,encoding=‘gbk‘) print(f.seek(4)) #输出;4 print(f.tell()) # 输出;4 print(f.truncate(8)) #输出;8 print(f.seek(0)) #输出 :0 f.close()
了解了以上的方法,我们就能愉快地进行文件修改操作了。
二、文件修改操作
当我们以读写(r+)模式打开文件时,,默认会把新增的内容追加到文件最末尾。
这是为什么呢?那我们如果想要修改中间的内容该怎么办呢?
还记得我们刚学过一个tell()方法吗,它的单位是字节,当我们读一段内容的时候,光标会跟着移动,文件读完了,光标就会移到末尾,
再接着写,光标自然会跟着移动,写完后,光标就停留在末尾了,我们可以用tell()方法验证一下猜想,打印此时光标位置,
此时,我们再想读文件内容,就没有任何输出了,都是空白的。这就解释了为何我追加的内容为何无法读出来。
至于为何追加内容会从末尾开始,就容易理解了,当你以追加模式打开文件时,光标会默认移到文件尾部,再开始写。
而文件修改就要用到另一个方法了,seek()方法,它的作用就是移动光标到指定位置,移动的单位是字节,当我们想修改某个地方,
使用seek()方法将光标移到指定位置就可以再修改了,下面我们可以试一下:
# write.txt的原本内容是 :这是第一个我用Python写的文件! # 现在我要将‘写’改为‘修改后’ f = open(file=‘write.txt‘,mode=‘r+‘,encoding=‘gbk‘) print(‘修改前:\n‘,f.read(),f.tell()) # 读出修改前的文件内容,并打印当前光标位置 f.seek(20) # 将光标移到第20个字节后的位置(GBK编码一个汉字占2字节,英文占1字节) f.write(‘修改后‘) # 写入修改内容 f.seek(0) # 将光标移到文件开头 print(f.tell()) # 打印当前光标位置 print(‘修改后:\n‘,f.read(),f.tell()) # 读出修改后的文件内容,并打印当前光标位置 f.close() # 关闭文件 ‘‘‘ 这是第一个我用Python写的文件! 29 0 修改后: 这是第一个我用Python修改后件! 29 ‘‘‘
没有报错,正常执行,‘写’ 也的确被改成了 ‘修改后’ ,文件大小也并未改变,但是也有我们不想修改的内容被覆盖了,这就尴尬了。。。
原因在这里:
这是硬盘的存储原理导致的,当你把文件存到硬盘上,就在硬盘上划了一块空间,存数据,等你下次打开这个文件 ,seek到一个位置,每改一个字,就是把原来的覆盖掉,如果要插入,是不可能的,因为后面的数据在硬盘上不会整体向后移。所以就出现 当前这个情况 ,你想插入,却变成了会把旧内容覆盖掉。
解决方法呢?
想修改当然可以,但是不要在硬盘上修改,把内容全部读到内存里,数据在内存里可以随便增删改查,修改之后,把内容再全部写回硬盘,把原来的数据全部覆盖掉。
例如:
# -*- coding:utf-8 -*- import os # 导入模块 f1 = ‘notebook.txt‘ # 待修改的文件 f2 = ‘note_new.txt‘ # 修改后的文件 f_old = open(f1,mode=‘r‘,encoding=‘utf-8‘) # 打开待修改的文件 f_new = open(f2,mode=‘w‘,encoding=‘utf-8‘) # 写入修改的文件 old_str = ‘一‘ # 待修改的字符串 new_str = ‘one‘ # 修改后的字符串 count = 0 # 统计修改次数 for line in f_old: # 循环读 if old_str in line: newline = line.replace(‘一‘,‘one‘) # 替换 count += 1 # 每修改一次自增1 else: newline = line f_new.write(newline) # 写入修改后的文件 f_old.close() # 依次关闭 f_new.close() os.replace(‘note_new.txt‘,‘notebook.txt‘) # 用新文件里的内容替换旧文件 print(‘修改次数:‘count) # 修改次数:5
原文地址:https://www.cnblogs.com/schut/p/8410961.html