1

本文主要讨论一下文件的三种可读可写模式的特点及互相之间的区别,以及能否实现修改文件的操作
由于前文已经讨论过编码的事情了,所以这里不再研究编码,所有打开操作默认都是utf-8编码(Linux系统下)

首先我们看r+(读写)

既然r+既能读又能写,那么能否实现在r+模式下进行文件的修改呢?答案是肯定的!,但是,有一点你需要注意,除非你知道在确切的位置修改确切的内容,否则往往不会得到你期望的结果。举个例子如下:
我们有这样一个文本“十步杀一人,千里不留行”
假设有这样一个需求,把“十步杀一人”改成“十步杀一个土匪”,初步设想是:用read(4)读取到汉字“一”,然后写入汉字“个土匪”:

with open('job', mode='r+') as f:
    print('先读取四个字符:',f.read(4))
    print('读取后的指针位置:',f.tell())
    f.write('个土匪')
    f.seek(0)
    print(f.read())
    输出为:
    先读取四个字符: 十步杀一
    读取后的指针位置: 12
    十步杀一人,千里不留行个土匪

从结果可以看到,使用read(4)指针确实移动到了指定的位置,但是写入的时候却没有按照设想,而是跑到了文件的末尾。这个原因涉及到一个叫“CHUNK”的东西,俺滴老师没教,我也不好深说,等深入理解它后再和你们讲哈😅😅😅

那么我们只说解决办法,可以用seek()手动定位指针,让它处在12的位置,然后再写入:

with open('job', mode='r+') as f:
    print('先读取四个字符:',f.read(4))
    print('读取后的指针位置:',f.tell())
    f.seek(f.tell())
    f.write('个土匪')
    f.seek(0)
    print(f.read())
    输出:
    先读取四个字符: 十步杀一
    读取后的指针位置: 12
    十步杀一个土匪里不留行

从结果可以看出,它确实是把人字改成了“个土匪”,可是它却把后面的字给覆盖了,这完全不是我们想要的结果,那么为什么呢?
原因就是:当文件写入磁盘后,磁盘会分出一块空间(实际上应该叫多个存储元的集合,具体请参考我另外一篇文章),这块空间是固定的,当你定位指针修改已经存在的内容时,相邻的后面的内容并不会给你要写入的内容“让地方”,也就是说你可以对它进行覆盖操作,但是你不能让后面的内容挪地方(这么说直白不?应该能明白吧。), 因此,虽然我们想要修改的是人这个字,但是由于你写入了“个土匪”三个字,所以后面的内容被覆盖了,变成了“十步杀一个土匪里不留行”。

接下来我们看看w+(写读模式)

w+,也就是写读操作,仍然对文件libai2操作,需求还是上例的需求

with open('libai2','w+') as f:
    content = f.read(25)#读取25个字符,这其中包括24个中文汉字或符号 和 一个换行符
    print('读取操作后的指针位置:',f.tell())#指针处在0,那么意味着文件内容是空的
    f.write('五')#然后我们写入中文汉字:“五”,期待能覆盖掉原来的“十”
    print('写入操作后的指针位置:',f.tell())#结果发现指针在3字节的位置,也就是一个汉字五的后面
    f.seek(0) 
    print(f.read())
读取操作后的指针位置: 0
写入操作后的指针位置: 3
五

我们可以看到整个文件的内容消失了,只有一个汉字“五”
这是因为w开头的模式会先进行判断,如果文件已存在则打开文件,并且清空文件内容。如果该文件不存在,则创建新文件。
所以当使用w+这种模式打开文件的那一刻,这个文件原本的内容就已经消失了。

最后我们看看a+(追加写读模式)

我们在后台从新创建了一个libai3文件,里面还是只包含那两句诗

with open('libai3','a+') as f: 
        print('初始指针位置',f.tell()) 
#初始指针位置是146,48个汉字或字符 加2个换行符,48*3+2=146
#由此可以看出,初始文件指针处在文件末尾位置
        f.seek(73) #我们把指针调整到73字节的位置,也就是汉字“十”的前面
        print('调整指针在73字节的位置:',f.tell())
        f.write('五')#然后我们写入汉字“五”
        f.seek(0) #调整指针到文件头部位置
        print(f.read()) #输出文件看看发生了什么
初始指针位置 146
调整指针在73字节的位置: 73
赵客缦胡缨,吴钩霜雪明。银鞍照白马,飒沓如流星。
十步杀一人,千里不留行。事了拂衣去,深藏身与名。
五

我们发现汉字“五”还是被写在了文件末尾

总结

w+和a+无法完成文件的修改操作,r+可以实现修改的操作,但是结果往往和我们预期的不太一样,当然,除非你知道要把确切的内容换成确切的新内容,不过感觉这个应用价值不大吧?


格瑞姆瑞坡
34 声望4 粉丝