day 14 文件操作
计算机数据存储
计算机内存分为运行内容和硬盘两种:保存在运行内存中的数据在程序运行结束后会自动释放
保存在硬盘中的数据会一直存在,除非手动删除或硬盘损坏
数据持久化 — 以文件为单位,将数据保存到硬盘中。
数据持久化又叫数据本地化,指的就是将程序中数据保存在硬盘中(程序中的数据默认是保存在运行内存中)
硬盘保存数据的基本单位是文件,如果想要把数据保存到硬盘中,就需要将数据保存到文件中。
常见的数据持久化:数据库(.db、.sqlite)、excel文件、csv文件、txt文件、json文件、plist文件
文件操作 — 操作文件内容(需要将文件打开才能执行的操作)
文件操作基本操作:打开文件 – 操作文件内容(读或写) — 关闭文件(
代码操作会自动保存,故这里不需要保存操作)
1. 打开文件
open(文件路径,文件打开方式(默认r),encoding = 文本文件编码方式)
1) 文件路径 – 文件在计算机中的位置信息
文件路径分为两种:绝对路径和相对路径
- 绝对路径:文件在计算机的全路径
# 绝对路径(windows电脑路径前加r或R 消除转义字符的影响)
open(r'D:\dell\Documents\python2301\02语言基础\day14文件操作\files\data1.txt')
# 找绝对路径可以在命令提示符中直接将文件拖进去就可以看到其绝对路径
-
相对路径
a. 在写路径时用 . 表示当前目录(当前写代码的代码文件所在文件夹)
b. 在写路径时用 … 表示当前目录的上层目录
注意:使用相对路径之前,需要将所操作文件放在当前工程目录中
注意:路径是以./开始的,./可以省略
# 相对路径
open(r'./files/data1.txt')
open(r'../day14文件操作/files/data1.txt')
# 综上所述路径在找不到指定文件时会报错,没有报错就说明路径正确的
2)文件打开方式
决定打开文件后能做什么(读或写);决定操作文件时的数据类型(字符串或二进制)
第一组值:r、w、a
r: 只读; 如果文件不存在则会报错
w: 只写,打开时会先清空原文件; 文件不存在则会自动创建这个文件
a: 只写,直接在原文件后面写新的东西,原文件不会清空; 文件不存在会自动创建这个文件
第二组值:t、b (第二组值可以不写,不写是默认t)
t: 字符串类型(读到的数据,和写入文件的数据必须是字符串)
b: 二进制类型(bytes;读到的数据,和写入文件的数据必须是二进制)
给打开方式赋值的时候必须在两组值中每一组选一个值,如果第二组不选默认选中 t:
rt(tr、r)、rb(br)、wt(tw、w)、wb(bw)、at(ta、a)、ab(ba)
如果需要将字符串、二进制以外数据写入文件,可以先对数据做一个字符串转换,将其转换为字符串即可
每一组值只能选一个,例如r和w不能一起
# ------------------ r 只读---------------------
f = open(r'files/data1.txt', 'r')
f.read()
# f.write('abc') 会报错,因为r只读不能写
# ------------------a是只写,不会清空原文件---------
f = open(r'files/data1.txt', 'a')
f.write('abc')
# ------------------w 只写 且清空原文件------------
f = open(r'files/data1.txt', 'w')
f.write('abc')
# -----r 打开不存在文件程序报错------------------------
f = open(r'files/data2.txt', 'r') # 报错
# -----w和a打开不存在文件时不会报错,且会自动创建这个文件--
f = open(r'files/data2.txt', 'w')
f = open(r'files/data3.txt', 'a')
# ---------------t - 字符串; b - 二进制 ------------
f = open(r'files/data1.txt', 'rt')
result = f.read()
print(type(result)) # <class 'str'>
#
f = open(r'files/data1.txt', 'r')
result = f.read()
print(type(result)) # <class 'str'> 第二组值不写时,默认是t
#
f = open(r'files/data1.txt', 'rb')
result = f.read()
print(type(result)) # <class 'bytes'>
3)文本文件编码方式
补充:常见的计算机内存单位
位(bit)
字节(bytes) 1字节=8位
kb 1kb = 1024字节
mb 1mb=1024kb
G 1G =1024mb
T 1T =1024G
文本文件编码方式
文本文件:全是文字信息,且打开后能编辑内容的文件 如word文件、txt文件、excel文件
与文本文件相反的是二进制文件如图片、音频、pdf文件
不同的文本文件编码方式,在保存同一个符号的编码值是采用的字节数(内存)不同
常见的文本文件编码方式:utf-8(推荐) 、 gbk
utf-8: 一个数字和字母采用一个字节保存;一个中文用三个字节
gbk : 一个数字和字母采用一个字节保存;一个中文用两个字节
使用编码方式的要求:前后一致(存储数据的时候采用的编码值必须和获取数据的时候采用的编码值一致)
前后编码与解码方式不一致,读的时候会报错或者乱码
若写入的是英文,即使解码编码前后不一致,读的时候也不会有问题。
f = open('files/data2.txt', 'w', encoding='utf-8')
f.write('hello! 世界! 哈哈哈!')
f = open('files/data2.txt', 'r', encoding='gbk')
print(f.read())
# 前后编码与解码方式不一致,读的时候会报错或者乱码
2. 操作文件
1)文件读操作 获取文件内容
a. 文件对象.read()— 获取整个文件内容(从读写位置开始获取到文件结束,读写位置默认在文件开头)
b. 文件对象.readline() – 从读写位置开始到一行结束
读完所有行后再读的结果是一个空串’’
注意: 读写操作会随着读操作而改变,第一次读获取后,再读获取,则第二次获取的结果为空
文件对象.seek(0) – 将读写位置移动到文件开头
f = open('files/data3.txt', 'r', encoding='utf-8')
result = f.read()
print(result)
print('------------------------------------------------------------分割线来啦!-----------------------------------------')
result1 = f.read()
print(result1) # 第一次读获取后,再读获取,则第二次获取的结果为空
# ---- 练习:读文件内容,一行一行的读 ------------------------
def get_file_content(path:str):
f = open(path, 'r', encoding='utf-8')
while True:
result = f.readline()
yield result
if result == '':
break
reader = get_file_content('files/data1.txt')
print(next(reader))
print(next(reader))
print(next(reader))
2)文件写操作 对文件内容进行增删改
文件对象.write(内容) — 将指定内容写入指定文件,注意内容的数据类型与打开方式有关
3. 关闭文件
文件对象.close()
f = open('files/data2.txt', 'w', encoding='utf-8') # 打开一次清空一次
f.write('Python') # 写的时候不清空
f.write('角度') # 接着写
f.close() # 文件关闭后不能再操作文件内容了
数据持久化应用
数据持久化方法 – 让这次运行程序产生的数据可以在下一次运行程序的时候使用
第一步:确定需要持久化的数据
第二步:创建文件,并且确定文件初始内容
第三步:做到在程序中需要这个数据时从文件中获取这个数据
第四步:做到这个数据如果发生改变,必须将最新的数据更新到文件中
- 案例1:写程序打印程序运行次数
# 获取上一次运行的次数
f = open('files/Run Time.txt', 'r', encoding = 'utf-8')
count = int(f.read())
f.close()
# 次数加1
count += 1
print(count)
# 更新文件内容
f = open('files/Run Time.txt', 'w', encoding = 'utf-8')
f.write(str(count))
f.close()
- 练习1:运行一次程序就提示用户输入学生的名字
# 写入姓名
name = input('请输入学生的姓名:')
f = open('files/students.txt', 'a', encoding='utf-8')
f.write(name + ' ')
f.close()
# 打印
f = open('files/students.txt', 'r', encoding='utf-8')
result = f.read()
print(result)
f.close()
"""
姓名:小明
性别:男
年龄:18
[{'name':'小明','gender':男,'age':18}]
"""
name = input('请输入学生的姓名:')
gender = input('请输入学生的性别:')
age = int(input('请输入学生的年龄:'))
# 获取文件内容
try:
f = open('files/学生信息.txt', 'r', encoding='utf-8')
all_student = eval(f.read())
f.close()
except FileNotFoundError:
all_student = []
all_student.append({'name': name, 'gender': gender, 'age': age})
print(all_student)
f = open('files/学生信息.txt', 'w', encoding='utf-8')
f.write(str(all_student))
f.close()
作业:登陆注册退出界面
def login_page():
print('='*40)
print()
print('❀❀ 欢迎来到xxx管理系统 ❀❀'.center(40))
print('♥ 1. 登 录'.center(40))
print('♥ 2. 注 册'.center(40))
print('♥ 3. 退 出'.center(40))
print()
print('=' * 40)
try:
f = open('files/page.txt', encoding='utf-8')
record = eval(f.read())
except FileNotFoundError:
record = {}
choose = int(input('请选择(1~3):'))
if choose == 1:
user = input('请输入账号:')
pw = input('请输入密码:')
if user not in record:
print('该账号不存在,请先注册!')
elif record.get(user) == pw:
print('登录成功!')
else:
print('登陆失败,密码错误!')
elif choose == 2:
user = input('请输入账号:')
pw = input('请输入密码:')
if user in record:
print('注册失败,该账号已存在!')
else:
record[user] = pw
print('注册成功!')
else:
print('已退出界面。')
print('='*40)
f = open('files/page.txt', 'w', encoding = 'utf-8')
f.write(str(record))
f.close()
login_page()