python:从入门到放弃 06 文件处理
什么是文件
在进行文件处理之前,我们需要知道是什么是文件,文件即操作系统提供给应用程序来操作硬盘的虚拟概念,用户或应用程序对文件的操作,就是向操作系统发起调用,然后由操作系统完成对硬盘的具体操作。
文件处理流程
1.打开文件、创建文件
2.编辑文件内容
3.保存文件内容
4.关闭文件
文件的打开与关闭
f = open() # 打开
f = close() # 关闭
1.使用关键字打开文件
open(r'a.txt') # 相对路径
open(r'D:\py1\day09\a.txt') # 绝对路径
res = open(r'a.txt', 'r', encoding='utf8')
'''
open(文件的路径,文件的操作模式,文件的编码)
1.文件的路径是必须要写的
2.文件的操作模式、文件的编码有时候不用写
'''
在处理完文件后,我们需要使用close()关闭文件,然而这一个步骤非常的容易遗忘掉。
考虑到这一点,python提供了with关键字来帮我们管理上下文
# 1、在执行完子代码块后,with 会自动执行f.close()
with open('a.txt','w') as f:
pass
# 2、可用用with同时打开多个文件,用逗号分隔开即可
with open('a.txt','r') as read_f,open('b.txt','w') as write_f:
data = read_f.read()
write_f.write(data)
文件的读写模式
r read 只读模式:只能读不能写
w write 只写模式:只能写不能读
a append 只追加模式:在文件末尾添加内容
r模式
# r只读模式: 在文件不存在时则报错,文件存在文件内指针直接跳到文件开头
with open('a.txt',mode='r',encoding='utf-8') as f:
res=f.read() # 会将文件的内容由硬盘全部读入内存,赋值给res
w模式
# w只写模式: 在文件不存在时会创建空文档,文件存在会清空文件,文件指针跑到文件开头
with open('b.txt',mode='w',encoding='utf-8') as f:
f.write('你好\n')
f.write('我好\n')
f.write('大家好\n')
f.write('111\n222\n333\n')
#强调:
# 1 在文件不关闭的情况下,连续的写入,后写的内容一定跟在前写内容的后面
# 2 如果重新以w模式打开文件,则会清空文件内容
a模式
# a只追加写模式: 在文件不存在时会创建空文档,文件存在会将文件指针直接移动到文件末尾
with open('c.txt',mode='a',encoding='utf-8') as f:
f.write('44444\n')
f.write('55555\n')
#强调 w 模式与 a 模式的异同:
# 1 相同点:在打开的文件不关闭的情况下,连续的写入,新写的内容总会跟在前写的内容之后
# 2 不同点:以 a 模式重新打开文件,不会清空原文件内容,会将文件指针直接移动到文件末尾,新写的内容永远写在最后
+模式
r+ w+ a+ :可读可写
在平时工作中,我们只单纯使用r/w/a,要么只读,要么只写,一般不用可读可写的模式*
文件的操作模式
t模式
文本模式 是默认的模式
r rt
w wt
a at
1.该模式只能操作文本文件
2.该模式必须要指定encoding参数
3.该模式读写都是以字符串为最小单位
b模式
二进制模式 可以操作任意类型的文件
rb 不能省略b
wb 不能省略b
ab 不能省略b
1.该模式可以操作任意类型的文件
2.该模式不需要指定encoding参数
3.该模式读写都是以bytes类型为最小单位
文件的内置方法
# 读操作
.read() # 读取所有内容,执行完该操作后,文件指针会移动到文件末尾
.readline() # 读取一行内容,光标移动到第二行首部
.readlines() # 读取每一行内容,存放于列表中
.readable() # 判断当前文件是否可读
# 强调:
# f.read()与f.readlines()都是将内容一次性读入内容,如果内容过大会导致内存溢出,若还想将内容全读入内存,则必须分多次读入,有两种实现方式:
# 方式一
with open('a.txt',mode='rt',encoding='utf-8') as f:
for line in f:
print(line) # 同一时刻只读入一行内容到内存中
# 方式二
with open('1.mp4',mode='rb') as f:
while True:
data=f.read(1024) # 同一时刻只读入1024个Bytes到内存中
if len(data) == 0:
break
print(data)
# 写操作
.write('1111\n222\n') # 针对文本模式的写,需要自己写换行符
.writelines(['333\n','444\n']) # 文件模式
.writable() # 判断文件是否可写
.flush() # 相当于主动按了ctrl+s(保存)
主动控制文件内光标移动
#大前提:文件内指针的移动都是Bytes为单位的,唯一例外的是t模式下的read(n),n以字符为单位
with open(r'a.txt','r',encoding='utf8') as f:
print(f.read(3))
print(f.read(3))
# read在二进制模式下 括号内的数字表示的是读取指定的字节数
with open(r'a.txt', 'rb') as f:
print(f.read(9).decode('utf8'))
print(f.read(1).decode('utf8'))
.seek(offset,whence) # offset:控制移动的字节数 whence:控制模式
'''
0: 默认的模式,该模式代表指针移动的字节数是以文件开头为参照的
1: 该模式代表指针移动的字节数是以当前所在的位置为参照的
2: 该模式代表指针移动的字节数是以文件末尾的位置为参照的
强调:其中0模式可以在t或者b模式使用,而1跟2模式只能在b模式下用
'''
文件的修改
# 文件a.txt内容如下
张一蛋 山东 179 49 12344234523
李二蛋 河北 163 57 13913453521
王全蛋 山西 153 62 18651433422
# 执行操作
with open('a.txt',mode='r+t',encoding='utf-8') as f:
f.seek(9)
f.write('<妇女主任>')
# 文件修改后的内容如下
张一蛋<妇女主任> 179 49 12344234523
李二蛋 河北 163 57 13913453521
王全蛋 山西 153 62 18651433422
实际上,我们并不能修改在硬盘上的数据,所以我们将硬盘中文件内容读入内存,然后在内存中修改完毕后再覆盖回硬盘。具体的实现方式有2种。
文件修改方式一
# 实现思路:将文件内容发一次性全部读入内存,然后在内存中修改完毕后再覆盖写回原文件
# 优点: 在文件修改过程中同一份数据只有一份
# 缺点: 会过多地占用内存
with open('db.txt',mode='rt',encoding='utf-8') as f:
data=f.read()
with open('db.txt',mode='wt',encoding='utf-8') as f:
f.write(data.replace('kevin','SB'))
文件修改方式二
# 实现思路:以读的方式打开原文件,以写的方式打开一个临时文件,一行行读取原文件内容,修改完后写入临时文件...,删掉原文件,将临时文件重命名原文件名
# 优点: 不会占用过多的内存
# 缺点: 在文件修改过程中同一份数据存了两份
import os
with open('db.txt',mode='rt',encoding='utf-8') as read_f,\
open('.db.txt.swap',mode='wt',encoding='utf-8') as wrife_f:
for line in read_f:
wrife_f.write(line.replace('SB','kevin'))
os.remove('db.txt')
os.rename('.db.txt.swap','db.txt')
小作业
1.编写一个简易版本的拷贝程序
路径全部自定义
file_path = input(r'输入文件的路径>>>>')
with open(r'test.txt', 'r', encoding='utf8') as test1:
ste = test1.read()
with open(file_path, 'a', encoding='utf8') as test2:
test2.write(ste)
2.结合文件编写用户注册登录功能
# 提前先创建一个空的userinfo.txt
用户注册 数据保存到文件中
用户登录 数据来源于文件
1.必须给我写出来
单用户注册登录
2.拔高练习
多用户注册登录
while True:
print('1.注册 2.登录')
inp = input('输入编号选择功能')
if inp == '1':
username_inp = input('请输入用户名>>>')
password_inp = input('请输入密码>>>')
user_str = username_inp + '|' + password_inp + '\n'
with open(r'userinfo.txt', 'a', encoding='utf8') as test:
test.write(user_str)
if inp == '2':
username_inp = input('请输入用户名>>>')
password_inp = input('请输入密码>>>')
user_str = username_inp + '|' + password_inp + '\n'
with open(r'userinfo.txt', 'r', encoding='utf8') as test:
for i in test:
if i == user_str:
print('登录成功')
break
else:
print('登录失败')