3.4 文件处理
本节重点:
使学生掌握文件的读、写、修改方法
掌握文件处理模式的区别
本节时长需控制在50分钟内
引子
1.问题:给你一个文件 "兼职白领学生空姐模特护士联系方式.txt" ,如何查看内容?
答:
安装文本编辑器软件
选中右键,利用文本编辑器软件打开
查看 or 写入
保存,关闭
PS: 看到居然还有xxx的女朋友 或 美好的事物应该分享,默默的把xxx的女朋友电话也写进去
2.问题:文件在硬盘上是如何存储?
答:以某种编码格式的 “010101010101001” 保存在硬盘上。
3.问题:假定世上无文本编辑器软件,如何使用Python对文件进行操作?
答:请看下面
Python处理文件
文件操作分为读、写、修改,我们先从读开始学习
读文件
示例1:
上述操作语法解释:
PS: 此处的encoding必须和文件在保存时设置的编码一致,不然“断句”会不准确从而造成乱码。
示例2:
上述操作语法解释:
问:示例2和示例1的区别在哪?
答:在于示例2打开文件时并未指定encoding,这是为何?是因为直接以rb模式打开了文件 ,rb是指二进制模式,数据读到内存里直接是bytes格式,如果想内容,还需要手动decode,因此在文件打开阶段,不需要指定编码
问:假如你不知道你要处理的文件是什么编码可怎么办呢?
输出:
注意:
文件操作时,以 “r”或“rb” 模式打开,则只能读,无法写入;
硬盘上保存的文件都是某种编码的0101010,打开时需要注意:
rb,直接读取文件保存时原生的0101010,在Python中用字节类型表示
r和encoding,读取硬盘的0101010,并按照encoding指定的编码格式进行断句,再将“断句”后的每一段0101010转换成unicode的 010101010101,在Python中用字符串类型表示
循环文件
写文件
上术操作语法解释:
二进制写
上述操作语法解释:
注意:
文件操作时,以 “w”或“wb” 模式打开,则只能写,并且在打开的同时会先将内容清空。
写入到硬盘上时,必须是某种编码的0101010,打开时需要注意:
wb,写入时需要直接传入以某种编码的0100101,即:字节类型
w 和 encoding,写入时需要传入unicode字符串,内部会根据encoding制定的编码将unicode字符串转换为该编码的 010101010
追加
把内容追加到文件尾部
运行结果
注意:
文件操作时,以 “a”或“ab” 模式打开,则只能追加,即:在原来内容的尾部追加内容
写入到硬盘上时,必须是某种编码的0101010,打开时需要注意:
ab,写入时需要直接传入以某种编码的0100101,即:字节类型
a 和 encoding,写入时需要传入unicode字符串,内部会根据encoding制定的编码将unicode字符串转换为该编码的 010101010
读写模式
打开模式只有只读、只写、只追加,难道没有可以读写的操作吗?当然有
读写模式
但上面的内容写到哪个位置了呢?答案是追加到了最后面。
那如果是我想添加到任意位置呢?答案是可以,又是不可以。。。。,为啥,一会就学
写读模式
输出
此时查看文件 内容 发现,里面只有4条newline..内容,之前的旧内容全没了,事实代表,w+会先把文件清空,再写新内容,相比w模式,只是支持了一个读功能,且还只能读已经写入的新内容。着实没什么卵用。。。
文件操作的其它功能
每个都举例试一下。
现在提出一个萦绕心头的问题,文件内容是否可修改?当然可以,但需要套路
修改文件
尝试直接以r+模式打开文件,默认会把新增的内容追加到文件最后面。但我想要的是修改中间的内容 ,怎么办? 为什么会把内容添加到尾部呢?(最新测试r+会从头覆盖,测试代码如下)
我们已经学了seek,现在告诉你,之所以内容会追加到最后面,是因为,文件一打开,要写的时候,光标会默认移到文件尾部,再开始写。 现在我想修改中间部分,是不是seek(中间位置)再写就可以了呢?
执行没报错,开心,看输出
确实从第3个字开始改的,但是我擦,好像我的[路飞学城] 把后面的内容覆盖啦。。。。,这不是我想要的呀。。。
问:为什么这样子?
这是硬盘的存储原理导致的,当你把文件存到硬盘上,就在硬盘上划了一块空间,存数据,等你下次打开这个文件 ,seek到一个位置,每改一个字,就是把原来的覆盖掉,如果要插入,是不可能的,因为后面的数据在硬盘上不会整体向后移。所以就出现 当前这个情况 ,你想插入,却变成了会把旧内容覆盖掉。
问:但是人家word, vim 都可以修改文件 呀,你这不能修改算个什么玩意?
我并没说就不能修改了,你想修改当然可以,就是不要在硬盘上修改,把内容全部读到内存里,数据在内存里可以随便增删改查,修改之后,把内容再全部写回硬盘,把原来的数据全部覆盖掉。vim word等各种文本编辑器都是这么干的。
问:说的好像有道理,但你又没看过word软件的源码,你凭什么这么笃定?
哈哈,我不需要看源码,硬盘 的存储原理决定了word必须这么干 ,不信的话,还有个简单的办法来确认我说的,就是用word or vim读一个编辑一个大文件 ,至少几百MB的,你 会发现,加载过程会花个数十秒,这段时间干嘛了? cpu 去玩了?去上厕所啦? 当然不是,是在努力把数据 从硬盘上读到内存里。
问:但是文件如果特别大,比如5个GB,读到内存,就一下子吃掉了5GB内存,好费资源呀,有没有更好的办法呢?
如果不想占内存,只能用另外一种办法啦,就是边读边改, 什么意思? 不是不能改么?是不能改原文件 ,但你可以打开旧文件 的同时,生成一个新文件呀,边从旧的里面一行行的读,边往新的一行行写,遇到需要修改就改了再写到新文件 ,这样,在内存里一直只存一行内容。就不占内存了。 但这样也有一个缺点,就是虽然不占内存 ,但是占硬盘,每次修改,都要生成一份新文件,虽然改完后,可以把旧的覆盖掉,但在改的过程中,还是有2份数据 的。
问:还有更好的方式 么?
有完没完? 没了。
占硬盘方式的文件修改代码示例
上面的代码,会生成一个修改后的新文件 ,原文件不动,若想覆盖原文件
练习题
练习题1 —— 全局替换程序:
写一个脚本,允许用户按以下方式执行时,即可以对指定文件内容进行全局替换
替换完毕后打印替换了多少处内容
练习题2 —— 模拟登陆:
用户输入帐号密码进行登陆
用户信息保存在文件内
用户密码输入错误三次后锁定用户,下次再登录,检测到是这个用户也登录不了
Last updated
Was this helpful?