文件操作
1. 计算机数据存储
- 计算机内存分为运行内存和硬盘两种:
- 保存在运行内存中的数据在程序运行结束后会自动释放
- 保存在硬盘中的数据会一直存在,除非手动删除或硬盘损坏。
2. 数据持久化
以文件为单位,将数据保存到硬盘中
-
数据持久化又叫数据本地化,指的是将程序中的数据保存在硬盘中(程序的数据默认是保存在运行内存中的)
-
硬盘保存数据的基本单位是文件,如果想要把数据保存到硬盘中需要把数据保存到文件中
-
常见的数据持久化:数据库(.db、.sqlite)、excel文件、csv文件、txt文件、json文件、plist文件等
3. 文件操作
操作文件内容
- 文件操作基本步骤:打开文件 -> 操作文件内容(读操作、写操作)-> 关闭文件
3.1 打开文件
- open(文件路径, 文件打开方式=‘r’, encoding=文本文件编码方式)
1)文件路径
文件在计算机中的位置信息
文件路径分为两种:绝对路径和相对路径
-
绝对路径:文件在计算机中的全部路径
-
相对路径:
- 在写路径的时候用’.'表示当前目录
- 在写路径的时候用’. .'表示当前目录的上层层目录
注意:使用相对路径之前需要先将被操作的文件放在工程目录中
注意:路径是以‘./‘开头的时候,’./'可以省略
# 使用绝对路径
open(r'E:\python\语法课\day14-文件操作\files\data1.txt')
# 使用相对路径
open(r'./files/data1.txt')
open(r'../day14-文件操作/files/data1.txt')
2)文件打开方式
决定了打开文件后能做什么(能读还是能写);还决定才做文件的时候数据的类型(是字符串还是二进制)
-
第一组值:r、w、a
- r - 只读
- w - 只写,打开的时候会先清空原文件(只要打开就清空),文件不存在会创建
- a - 只写,打开的时候不会清空原文件,直接追加到后面,文件不存在会创建
-
第二组:t、b
- t - 字符串类型(读到的数据,和写入文件中的数据必须是字符串)
- b - 二进制(bytes;读到的数据,和写入文件的数据必须是二进制)(二进制文件只能用b打开)
给打开方式复制的时候必须在两组值中每一组选一个值,如果第二组不选默认选择t
rt(tr、r)、rb(br)、wt(tw、w)、wb(bw)、at(ta、a)、ab(ba)
注意:以b是方式打开文件,encoding不能赋值
# --------- r 是只读----------------
f = open(r'./files/data1.txt', 'r')
f.read()
# f.write() # 报错
# --------- a 是只写, 并不会清空原文件----------------
f = open(r'./files/data1.txt', 'a')
# f.read() # 报错
f.write('abc') # hello world!abc
# --------- w 是只写, 并会清空原文件----------------
f = open(r'./files/data1.txt', 'w')
# f.read() # 报错
f.write('abc') # 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 - 数据类型是字符串 ----------------
f = open(r'./files/data2.txt', 'rt')
result = f.read()
print(type(result)) # <class 'str'>
f = open(r'./files/data2.txt', 'at')
# f.write(100) # 100不是字符串会报错
f.write('100')
# --------- b - 数据类型是二进制 ----------------
f = open(r'./files/data2.txt', 'rb')
result = f.read()
print(type(result)) # <class 'bytes'>
f = open(r'./files/data2.txt', 'ab')
# f.write(100) # 100不是二进制数据会报错,写入的内容需要时二进制类型
3)文本文件编码方式
不同的文本文件编码方式,在保存一个符号的编码值的时候采用的字节数不同
常见的文本文件编码方式: utf-8(推荐), gbk
-
utf-8:一个数字字母采用一个字节保存;一个中文用三个字节
-
gbk:一个数字字母采用一个字节保存;一个中文用两个字节
使用编码方式的要求:前后一致(存储数据的时候采用编码值必须和获取数据的时候采用的编码值一致)
补充:常见的计算机内存单位
位(bit)
1字节(bytes) = 8位
1kb = 1024字节
1mb = 1024kb
1G = 1024mb
1T = 1024G
# 当含中文时,存和读时,编码方式要一致,若只是英文、数字,存和读时可以不一样
# -------------urf-8 存含中文内容 ------------------------
f = open(r'./files/data4.txt', 'w', encoding='utf-8')
f.write('hello! 世界!')
# -------------urf-8 读urf-8存内容 ------------------------
f = open(r'./files/data4.txt', 'r', encoding='utf-8')
print(f.read()) # hello! 世界!
# -------------gbk 读urf-8存内容 ------------------------
f = open(r'./files/data4.txt', 'r', encoding='gbk')
# print(f.read()) # 报错
# -------------gbk 存含中文内容 ------------------------
f = open(r'./files/data4.txt', 'w', encoding='gbk')
f.write('hello! 世界!')
# -------------urf-8 读gkb存内容 ------------------------
f = open(r'./files/data4.txt', 'r', encoding='utf-8')
# print(f.read()) # 出错
# -------------urf-8 存英文、数字内容 ------------------------
f = open(r'./files/data4.txt', 'w', encoding='utf-8')
f.write('1hello! 2hello!')
# -------------gbk 读urf-8存的内容 ------------------------
f = open(r'./files/data4.txt', 'r', encoding='gbk')
print(f.read()) # hello! hello!
3.2 操作文件
1)文件读操作 - (获取文件内容)
-
文件对象.read()
获取整个文件内容(从读写位置开始获取文件结束,读写位置默认文件开头)
-
readline()
从读写位置开始读到文件结束(之针对文本文件有效)
注意:读操作会改变读写位置
文件对象.seek(0) - 将读写位置移动到文件开头
2)文件写操作 - (包括增加内容、修改内容和删除内容)
-
文件对象.write(内容)
将指定内容写入到指定文件中
3)关闭文件
- 文件对象.close()
- 使用后会自动关闭文件
with open(文件路径, 文件打开方式=‘r’, encoding=文本文件编码方式) as 文件对象:
代码块
f = open(r'./files/data1.txt', encoding='utf-8')
result = f.read()
print(result)
print('------------------------------华丽分割线-----------------------------')
result = f.read()
print(result) # 空,光标位置已改变到结束位置,此时读读不到
print('------------------------------华丽分割线-----------------------------')
f.seek(0) # 光标移到文件开头,读就可以读得到
result = f.read()
print(result)
文件对象.readlined()
f.seek(0)
print(f.readline()) # 锄禾日当午,
print(f.readline()) # 汗滴禾下土。
print(f.readline()) # shuizhipanzhngcan
print(f.readline()) # ''
result = f.readline()
print(type(result), len(result)) # <class 'str'> 0
一行一行的读取data3
# 方法1:一次性一行一行读完
f = open(r'./files/data3.txt', encoding='utf-8')
while True:
result = f.readline()
print(result)
if result == '':
break
def get_file():
f = open(r'./files/data3.txt', encoding='utf-8')
while True:
result = f.readline()
yield result
if result == '':
break
reader = get_file()
print(next(reader)) # 锄禾日当午,
print(next(reader)) # 汗滴禾下土。
print(next(reader)) # 谁知盘中餐,
文件对象.close()
f = open(r'./files/data2.txt', 'w', encoding='utf-8')
f.write('python')
f.write('\njava')
f.close()
# f.write('\nC') # 文件关闭后不能操作,会报错
2. 数据持久化的应用
2.1 数据持久化的方法
让这次运行产生的数据在下次运行程序的时候使用
第一步:确定需要持久化的数据
第二步:创建文件并且确定文件初始内容
第三步:做到在程序中需要这个数据的时候从文件中获取
第四步:做到这个数据如果发生改变必须将最新的数据更新到文件中
案例1:写程序打印程序运行次数
获取上一次次数
f = open(r'files/runTime.txt', encoding='utf-8')
count = int(f.read())
f.close()
# 让次数加1
count += 1
# 打印次数
print(count)
# 更新文件内容
f = open(r'files/runTime.txt', 'w', encoding= 'utf-8')
f.write(str(count))
练习1:
请输入输入添加学生名字:小明
小明
请输入输入添加学生名字:小花
小明 小花
请输入输入添加学生名字:张三
小明 小花 张三
# 方法1
f = open(r'files/students.txt', encoding='utf-8')
names = f.read()
f.close()
name = input('请输入输入添加学生名字:')
names += name + ' '
print(names)
f = open(r'files/students.txt', 'w', encoding='utf-8')
f.write(names)
# 方法2
name = input('请输入输入添加学生名字:')
name += ' '
f = open(r'files/students.txt', 'a', encoding='utf-8')
f.write(name)
f = open(r'files/students.txt', encoding='utf-8')
names = f.read()
f.close()
print(names)
练习2
姓名:小明
性别:男
年龄:18
打印:[{‘name’: ‘小明’, ‘gender’: 男, ‘age’: 18}]姓名:小花
性别:女
年龄:18
打印:[{‘name’: ‘小明’, ‘gender’: ‘男’, ‘age’: 18}, {‘name’: ‘小花’, ‘gender’: ‘女’, ‘age’: 18}]
# 需要持久化的数据:已添加添加学生信息
name = input('请输入输入添加学生名字:')
gender = input('请输入输入添加学生性别:')
age = int(input('请输入输入添加学生年龄:'))
# 之前添加过的所有学生
try:
f = open(r'files/学生信息.txt', encoding='utf-8')
all_student = eval(f.read())
f.close()
except FileNotFoundError:
all_student = []
all_student.append({'name': name, 'gender': gender, 'age': age})
f = open(r'files/学生信息.txt', 'w', encoding='utf-8')
f.write(str(all_student))
print(all_student)
写完后自动关闭文件
with open(r'./files/data2.txt', 'a', encoding='utf-8') as f:
f.write('python')
f.write('\njava')