📔 Python文件 学习笔记
文件概述
-
什么是文件?
- 文件是OS提供给用户/应用程序操作硬盘的一种虚拟的概念/接口
-
为何使用文件?
- 用户/应用程序可以通过文件将数据永久保存到硬盘中。即操作文件就是操作硬盘
- 用户/应用程序直接操作的是文件,对文件的所有操作,都是在向OS发送系统调用,然后再由操作将其转换成具体的硬盘操作。
-
如何使用文件:open()
- 控制文件读写内容的模式:t和b
- 强调:t和b不能单独使用,必须和r/w/a连用。
- t文本(默认模式):读写都是以str(unicode)为单位进行读写。
- 文本文件
- 必须指定encoding='utf-8'
- b二进制/bytes
| # 应用程序发起操作,所以操作系统会允许访问硬盘中的数据文件
f = open(r'./test.txt') # f的值是一种变量,占用的是应用程序的内存空间
print(f)
|
操作文件:读/写文件
应用程序对文件的读写请求都是在向操作系统发送系统调用,然后操作系统控制硬盘把输入读入内存、或者写入硬盘中。
| f = open(r'./test.txt')
print(f)
res =f.read() # 读取文件
f.close() # 回收操作系统资源
f.read() # 变量f还存在,但是不能进行读操作
del f # 回收应用程序资源,应用程序资源会自动回收
|
使用with语法 进行上下文管理
| # 没有指定encoding参数操作系统会使用自己默认的编码
# Linux和MAC OS系统默认是utf-8
# 在windows中系统默认是gbk
# 文件对象也可以称为文件句柄
# t 模式会将f.read()读出的结果解码出unicode
# with open(r'../test1.txt'b,mode='rt',encoding="utf-8") as f1:
with open(r'../test1.txt'b,mode='rt') as f1,open(r'../test2.txt',mode='rt') as f2: # 等价于 f1 = open(r'../test.txt',mode='rt')
res = f1.read()
print(res)
# with 会自动帮忙执行close
# f1.close()
# f2.close()
|
r 模式
| # r 默认的操作模式:只读模式,当文件不存在时就会直接报错,当文件存在时,文件指针就会跳转到开始位置
with open('./c.txt',mode = 'rt',encoding='utf-8') as f:
... # 类似PASS
print("第一次读".center(50,'*'))
res = f.read() # 把所有的内容从硬盘中读入内存
print(res)
# 读完文件后,指针在文件的最末尾,所以不会打印任何信息,如果使用with再次打开就会打印信息
print("第二次读".center(50,'*'))
res = f.read()
print(res)
|
案例演示:
| input_username = input("please input your user name : ").strip()
input_passwd = input("please input your user password : ").strip()
with open("user.txt",mode = "rt",encoding = "utf-8") as f:
for line in f:
# 如果是多行内容,则优先进行去除换行,再进行切分特定的符号
username.password = line.strip().split(':')
if input_username == username and input_passwd = password:
print("you are login successfully")
break
# else 归属于for循环
else:
print("please check your username or password,thx")
|
w 模式
| # w 只写模式,当文件不存在时则会直接创建文件,当文件存在时,会直接清空文件,指针位置在开始位置
with open("d.txt",mode = 'wt',encoding = 'utf-8') as f:
#f.read() 不可读,所以不能进行
f.write("This is w mode content")
# 注意点:
# 在w模式打开文件,没有关闭文件的情况下,连续写操作,不会覆盖,文件内容则会追加写
# 如果w模式重新打开文件,则会直接清空文件内容
|
案例演示
| # w模式用来创建全新的文件
# 文件的copy工具
src_file = input("source file : ").strip()
dest_file = input("destination file : ").strip()
with open(r'{}'.format(src_file), mode = 'rt', encoding = 'utf-8') as f1,\
open(r'{}'.format(dest_file),mode = 'wt', encoding = 'utf-8') as f2:
res = f1.read()
f2.write(res)
|
a 模式
| # a 只追加写,当文件不存在时会创建空文档,当文件存在时文件指针会直接跳转到末尾
with open('a.txt', mode = 'at', encoding = 'utf-8') as f:
#f.read() #会直接报错,不可读
#pass
f.write("This is a mode content") # 会追加到文件的末尾
#
|
- a模式和w模式的区别
- 相同点:打开文件不关闭的情况下,连续的写入内容都是会在原来的基础上添加
- 不同点:以a模式重新打开文件,不会清空原文件内容,会将文件指针直接移动到文件末尾。
+ 模式
不能单独使用,必须配合r、w、a模式
| with open(r'a.txt', mode = 'rt+',encoding = 'utf-8') as f:
print(f.read())
|
x 模式
x 模式(控制文件操作的模式)
只写模式,【不可读,不存在则创建,存在则直接报错】
b 模式
b模式:控制文件读写内容的模式
对于b模式,不进行任何转码操作,直接进行读入到内存中即可。
- 读写都是以Bytes为单位进行读写
- 任何文件都可以读写,例如mp4文件、jpg文件
- 一定不能指定字符编码参数encoding。
| # 例如:读取视频文件时,使用t模式就不行,因为t模式只能读取文本文件
with open('xxx.mp4',mode = 'rb') as f: # 二进制模式,不需要指定encoding,
f.read() # 硬盘的二进制文件直接读入内存
f.readline() # 一次读取一行
|
总结:
- f.read() 和 f.readlines() 都是将内容一次性读入到内存,如果内容过大会导致内存溢出。如果要将内容读入到内存中,必须分多次进行读入。两种实现方式:
-
写操作
f.writelines()
| # t 模式
with open(r'a.txt', mode = 'wt', encoding = 'utf-8') as f:
f.write('111\n222\n333\n')
l = ['11111\n','22222','33333']
for line in l:
f.write(line)
f.writelines(l) # write和writelines都是一次性读取内容写入到文件中
# b 模式
# 如果是纯英文字符,直接加前缀b得到bytes类型。
l = [
b'1111aaa\n',
b'22222',
b'333333'
]
# '上'.encode('utf-8') 等同于 bytes('上',encoding = 'utf-8')
l = [
bytes('上海',encoding = 'utf-8'),
bytes('北京',encoding = 'utf-8'),
bytes('深圳',encoding = 'utf-8')
]
|
了解
| with open(r'a.txt',mode = 'wt', encoding = 'utf-8') as f:
f.write('广州')
f.flush() # 大多数不执行,立刻将文件内容从内存刷新到硬盘中
f.writeable() # 文件是否可读
f.readable() # 文件是否可读
f.closed() # 文件是否关闭
f.encoding # 如果文件打开模式为b,打印文件的格式
f.name # 打印文件的名字
|
文件指针移动
指针移动的单位都是以 bytes/字节 为单位。
只有一种情况特殊:t模式下的read(n), n表示字符的个数。
| with open(r'aaa.txt',mode = 'rt', encoding = 'utf-8') as f:
res = f.read(4)
print(res)
|
f.seek(n,模式)
| # f.seek(n,模式) :n 指的是移动的字节个数
# - 模式
# 模式 0:参照物是文件头的开头文件
f.seek(9,0)
f.seek(3.0) # 3
# 模式 1:参照物是当前指针所在位置
f.seek(9,1)
f.seek(3,1) # 12
# 模式 2:参照物是文件末尾位置,是倒着移动
f.seek(-9,2)
f.seek(-3.2) # 12
f.tell() # 获取文件指针当前位置
|
实现Linux中的tail 功能
| # f.seek的应用
with open('access.log', mode = 'rt',encoding = 'utf-8') as f:
# 将指针跳转到文件末尾
# f.read() # 会直接报错
f.seek(0,2) # 2是以末尾作为参照物,0是字节个数
while True:
f.readline() #
if len(line) == 0:
time.sleep(0.3)
else:
print(line.decode('utf-8'),end='') # end 可以去除空格
|
文件修改的两种方式
| with open(r'aaa.txt',mode='r+',encoding = 'utf-8') as f:
f.seek(9,0)
f.write("要写入的内容")
|
方式1:也就是现行文本编辑器采用的方式
| with open(r'a.txt',mode = 'rt', encoding = 'utf-8') as f:
res = f.read()
data = res.replace("King","SolerHO")
print(data)
with open(r'a.txt',mode = 'wt',encoding = 'utf-8') as f1:
f1.write(data)
|
方式2:
| with open(r'a.txt',mode = 'rt', encoding = 'utf-8') as f,\
open(r'a.txt.swamp',mode = 'wt',encoding = 'utf-8') as f1:
for line i f:
f1.write(line.replace("King","SolerHO")) #会产生新的文件占用,所以会进行删除和重命名
os.remove('a.txt') # 删除修改前的文件
os.rename('a.txt.swamp','a.txt') # 重新修改文件名字
|