文件操作
1.相对路径和绝对路径:
1.相对路径:同一个文件夹下的文件,相对于当前这个程序所在的文件夹而言,如果在同一个文件夹中则相对路径就是这个文件名,如果在上一层文件夹则要../
2.绝对路径:从磁盘根目录开始一直到文件名
我们更推荐大家使用相对路径.因为在我们把程序拷贝给别人使用的时候.直接把项目拷贝走就能运行. 但是如果用绝对路径.那还需要拷贝外部的文件.
2.初始文件操作:
使用open()函数来打开一个文件,获取到文件句柄,然后通过文件句柄对文件进行操作,根据打开方式的不同能够执行的操作也会有相应的差异
打开文件的方式:
r,w,a,r+,w+,a+,rb,wb,ab,r+b,w+b,a+b默认使用的是r(只读)模式
3.r,rb:只读操作:
需要注意的encoding表示编码集,根据文件的实际保存编码进行获取数据
rb读取的是bytes类型,在rb模式下,不能选择encoding字符集
with open('leagues_of_legends.txt', mode='r', encoding='UTF-8') as league: print(league.read()) league.close() ''' 1 Lee Sin 2 Ahri 3 Alistar '''
rb的作用:在读取非文本文件的时候,如MP3等时要用到rb,因为这种数据没办法直接显示出来的,看直播的数据也是这种
3.1read():讲文件中的内容全部读取出来,弊端:占内存.如果文件过大,容易导致内存崩溃
with open('leagues_of_legends.txt', mode='r', encoding='utf-8') as league: lis = league.read() league.close() print(lis)
3.2read(n):读取n个字符.需要注意的是.如果再次读取.那么会在当前位置继续去读而不是从头读,如果使用的是rb模式.则读取出来的是n个字节
with open('leagues_of_legends.txt', mode='r', encoding='utf-8') as league: lis = league.read(3) lit = league..read(3) league.close() print(lis) print("OK!") print(lit)
3.3readline(): 一次读取一行数据,注意:readline()结尾,注意每次读取出来的数据都会有一个\n所以呢.需要我们使用strip()方法来去掉\n或者空格
with open('leagues_of_legends.txt', mode='r', encoding='utf-8') as league: lis = league.readline() league.close() print(lis)
3.4readlines()将每一行形成一个元素,放到一个列表中.将所有的内容都读取出来.所以也是.容易出现内存崩溃的问题.不推荐使用
with open('leagues_of_legends.txt', mode='r', encoding='utf-8') as league: lis = league.readlines() league.close() print(lis)
3.5循环读取.这种方式是组好的.每次读取一行内容.不会产生内存溢出的问题.
with open('leagues_of_legends.txt', mode='r', encoding='utf-8') as league: for lines in league: print(lines) league.close()
注意:读取完的文件句柄一定要关闭file.close()
4.写模式:w,wb
注意:写模式下,如果没有文件.则会创建文件,如果文件存在.则将原件中原来的内容删除,再写入新内容,wb模式下.可以不指定打开文件的编码.但是在写文件的时候必须将字符串转化成utf-8的bytes数据
f = open("小娃娃", mode="wb") f.write("金毛狮王".encode("utf-8")) f.flush() f.close() with open('Lee Sin', mode='w',encoding='utf-8') as Lee: Lee.write("A master of Ionia's ancient martial arts, Lee Sin is a principled fighter who channels the essence of\n" "the dragon spirit to face any challenge. Though he lost his sight many years ago, the warrior-monk has\n" "devoted his life to protecting his homeland against any who would dare upset its sacred balance.\n" " Enemies who underestimate his meditative demeanor will endure his fabled burning fists and blazing\n" "roundhouse kicks.") Lee.flush() Lee.close() sin = open('Lee Sin', mode='r', encoding='utf-8') print(sin.readlines()) sin.close() with open('Lee', mode='wb') as lee: lee.write("Lee Sin".encode('utf-8')) lee.flush() lee.close() lee_sin = open('Lee', mode='r', encoding='utf-8') print(lee_sin.read()) lee_sin.close()
5.追加:a,ab
在追加模式下.我们写入的内容会追加在文件的结尾.
lee = open('Lee', mode='a', encoding='utf-8') lee.write('come from league of legends') lee.flush() lee.close() lee = open('Lee', mode='ab') lee.write('come from league of legends'.encode('utf-8')) lee.flush() lee.close()
6.读写模式:r+
对于读写模式.必须是先读.因为默认光标是在开头的.准备读取的.当读完了之后再进行写入.我们以后使用频率最高的模式就是r+
with open('Lee', mode='r+', encoding='utf-8') as lee: print(lee.read()) lee.write(" come from league of legends") lee.flush() lee.close() sin = open('Lee', mode='r', encoding='utf-8') print(sin.read())
** r+模式下.必须是先读取.然后再写入**
7.写读模式:w+
先将所有的内容清空.然后写入.最后读取.但是读取的内容是空的,不常用
with open('Lee', mode='w+', encoding='utf-8') as lee: lee.write("lee") lee.flush() print(lee.read()) lee.close()
w+模式下,一开始读取不到数据.然后写的时候再将原来的内容清空.所以,很少用,读不出数据
8.追加读:a+
a+模式下,不论先读还是后读.都是读取不到数据的.
with open('Lee', mode='a+', encoding='utf-8') as lee: print(lee.read()) lee.write("lee") lee.flush() print(lee.read()) lee.close()
9.其他相关操作
1.seek(n)
seek(n) 光标移动到n位置,注意,移动的单位是byte.所以如果是UTF-8的中文部分要是3的倍数.
通常我们使用seek都是移动到开头或者结尾.
def seek(self, offset: int, whence: int = 0) -> int:
pass
offset -- 开始的偏移量,也就是代表需要移动偏移的字节数
whence:可选,默认值为 0。给offset参数一个定义,表示要从哪个位置开始偏移;
0代表从文件开头开始算起,
1代表从当前位置开始算起,
2代表从文件末尾算起。
2.tell()使用tell()可以帮我们获取到当前光标在什么位置
3.truncate()截断文件
with open('Lee Sin', mode='r+', encoding='utf-8') as lee: lee.seek(0) print(lee.read()) lee.seek(0) lee.seek(0, 2) print(lee.read()) lee.seek(0) lee.write('Lee Sin ') lee.flush() lee.tell() lee.seek(0) lee.read() lee.seek(7) lee.truncate() lee.seek(0) lee.read() lee.close()
深坑请注意:在r+模式下.如果读取了内容.不论读取内容多少.光标显示的是多少.再写入或者操作文件的时候都是在结尾进行的操作.
所以如果想做截断操作.记住了.要先挪动光标.挪动到你想要截断的位置.然后再进行截断关于truncate(n),如果给出了n.则从开头开头进行截断,如果不给n,则从当前位置截断.后面的内容将会被删除
10.修改文件以及另一种打开文件的方式
文件修改:只能将文件中的内容读取到内存中,将信息修改完毕,然后将源文件删除,将新文件的名字改成老文件的名字.
import os with open('Lee', mode='r+', encoding='utf-8') as lee,\ open('lee sin', mode='w+',encoding='utf-8') as sin: for line in lee: new_line = line.replace('lee', 'Lee sin') sin.write(new_line) sin.flush() lee.close() sin.close() os.remove('Lee') os.rename('lee sin', 'Lee')
一次将所有内容进行读取.内存溢出.解决方案:一行一行的读取和操作
作者: 咕咚!
出处: https://www.cnblogs.com/linga/
关于作者:专注虚拟化,运维开发,RPA,Rust,Go,Python!
本文版权归作者和博客园共有,禁止*.csdn.net转载,禁止以盈利为目的的转载,转载文章,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 原文链接 如有问题, 可邮件(oldsixa@163.com)咨询.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)