【python学习笔记】11 python操作文件详解

本系列为自己学习Python的笔记,如有误,欢迎大家指正

前言

想一下我们平时用word操作一个文件的流程:

  1. 找到文件,双击打开
  2. 读或修改
  3. 保存&关闭

用python操作文件也差不多:

f=open(filename)  # 打开文件
f.write("我是梓莘") # 写操作
f.read()  #读操作
f.close() #保存并关闭

不过有一点是不同的Python只能以读、创建、追加 3种模式中的任意一种打开文件,不能即写又读。

操作模式

  • r 只读模式
  • w 创建模式,若文件已存在,则覆盖旧文件
  • a 追加模式,新数据会写到文件末尾

创建文件

f = open(file='./员工.txt',mode='w')
f.write("Andy  CEO  200000\n")
f.write("Lily  程序员  100000\n")
f.close()

只读模式

f = open(file='疫情监测数据.txt',mode='r')
print(f.readline())  # 读一行
print('------分隔符-------')
data = f.read()  # 读所有,剩下的所有
print(data)
f.close()

执行输出

大黄蜂   阴性
------分隔符-------
小猪佩奇  阴性

追加模式

f = open(file='疫情监测数据.txt',mode='a')
f.write("喜羊羊  阴性\n")  # 会追加到文件尾部
f.close()

循环文件

f = open(file='学生体检信息.txt',mode='r')
	for line in f:    
		line = line.split()    
		name,addr,height,weight,phone = line    
		height = int(height)    
		weight = int(weight)    
		if height > 170 and weight <= 50:        
			print(line)
f.close()

其它功能

def mode(self) -> str:
        返回文件打开的模式
def name(self) -> str:
        返回文件名
def fileno(self, *args, **kwargs): # real signature unknown
        返回文件句柄在内核中的索引值,以后做IO多路复用时可以用到
def flush(self, *args, **kwargs): # real signature unknown
        把文件从内存buffer里强制刷新到硬盘
def readable(self, *args, **kwargs): # real signature unknown
        判断是否可读
def readline(self, *args, **kwargs): # real signature unknown
        只读一行,遇到\r or \n为止
def seek(self, *args, **kwargs): # real signature unknown
        把操作文件的光标移到指定位置
        *注意seek的长度是按字节算的, 字符编码存每个字符所占的字节长度不一样。
        如“梓莘学习” 用gbk存是2个字节一个字,用utf-8就是3个字节,因此以gbk打开时,seek(4) 就把光标切换到了“莘”和“学”两个字中间。
        但如果是utf8,seek(4)会导致,拿到了飞这个字的一部分字节,打印的话会报错,因为处理剩下的文本时发现用utf8处理不了了,因为编码对不上了。少了一个字节
def seekable(self, *args, **kwargs): # real signature unknown
        判断文件是否可进行seek操作
def tell(self, *args, **kwargs): # real signature unknown
        返回当前文件操作光标位置 
def truncate(self, *args, **kwargs): # real signature unknown
        按指定长度截断文件
        *指定长度的话,就从文件开头开始截断指定长度,不指定长度的话,就从当前位置到文件尾部的内容全去掉。
    def writable(self, *args, **kwargs): # real signature unknown
        判断文件是否可写

混合模式

打开文件其实还有3种混合模式

w+ 写读 , 这个功能基本没什么意义,它会创建一个新文件 ,写一段内容,可以再把写的内容读出来,没什么卵用。

r+ 读写,能读能写,但都是写在文件最后,跟追加一样

a+ 追加读,文件 一打开时光标会在文件尾部,写的数据全会是追加的形式

r+模式

默认就是往文件 尾部写

修改文件

尝试直接以r+模式打开文件,默认会把新增的内容追加到文件最后面。但我想要的是修改中间的内容 ,怎么办? 为什么会把内容添加到尾部呢?

问:为什么原有数据会被覆盖呢?

这是硬盘的存储原理导致的,当你把文件存到硬盘上,就在硬盘上划了一块空间,存数据,等你下次打开这个文件 ,seek到一个位置,每改一个字,就是把原来的覆盖掉,如果要插入,是不可能的,因为后面的数据在硬盘上不会整体向后移。所以就出现 当前这个情况 ,你想插入,却变成了会把旧内容覆盖掉。

问:但是人家word, vim 都可以修改文件 呀,你这不能修改算个什么玩意?

我并没说就不能修改了,你想修改当然可以,就是不要在硬盘上修改,把内容全部读到内存里,数据在内存里可以随便增删改查,修改之后,把内容再全部写回硬盘,把原来的数据全部覆盖掉。vim word等各种文本编辑器都是这么干的。

问:说的好像有道理,但你又没看过word软件的源码,你凭什么这么笃定?

这是由硬盘 的存储原理决定的。比如用word or vim读一个编辑一个大文件 ,至少几百MB的,你 会发现,加载过程会花个数十秒,这些时间就是在努力的将数据从硬盘读到内存中。

问:但是文件如果特别大,比如5个GB,读到内存,就一下子吃掉了5GB内存,好费资源呀,有没有更好的办法呢?

如果不想占内存,只能用另外一种办法啦,就是边读边改, 什么意思? 不是不能改么?是不能改原文件 ,但你可以打开旧文件 的同时,生成一个新文件,边从旧的里面一行行的读,边往新的一行行写,遇到需要修改就改了再写到新文件 ,这样,在内存里一直只存一行内容。就不占内存了。 但这样也有一个缺点,就是虽然不占内存 ,但是占硬盘,每次修改,都要生成一份新文件,虽然改完后,可以把旧的覆盖掉,但在改的过程中,还是有2份数据的。

占硬盘方式的文件修改代码示例

f_name = "学生体检信息.txt"
f_new_name = "%s.new" % f_name
old_str = "梓莘"
new_str = "花花"
f = open(f_name,'r')
f_new = open(f_new_name,'w')
for line in f:
    if old_str in line:
        new_line = line.replace(old_str,new_str)
    else:
        new_line = line
    f_new.write(new_line)
f.close()
f_new.close()

上面的代码,会生成一个修改后的新文件 ,原文件不动,若想覆盖原文件

import os
f_name = "学生体检信息.txt"
f_new_name = "%s.new" % f_name
old_str = "梓莘"
new_str = "花花"
f = open(f_name,'r')
f_new = open(f_new_name,'w')
for line in f:
    if old_str in line:
        new_line = line.replace(old_str,new_str)
    else:
        new_line = line
    f_new.write(new_line)
f.close()
f_new.close()
os.rename(f_new_name,f_name) #把新文件名字改成原文件 的名字,就把之前的覆盖掉了,windows使用os.replace # 帮助文档说明replace会覆盖原文件

微信搜一搜【梓莘】或扫描下方二维码交个朋友共同进步。文章持续更新中。目前在整理python百战学习笔记,期待后续更多的更新哦。
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值