文件操作
---------------------文件操作
---------------------数据持久化
一、文件操作
# 1.数据持久化
'''
计算机内存分为两种:运行内存、硬盘(磁盘)
保存在运行内存中的数据在程序运行结束后会自动销毁;保存在硬盘中的数据除非人为删除或者磁盘损坏否则一直存在。
程序中数据默认是保存在运行内存中的。
数据持久化就是将数据以文件的形式保存到硬盘中。(保存到硬盘中的数据才能做到,这次运行程序产生的数据在下一次运行程序的时候还能使用)
'''
# 2.文件操作 - 打开文件后,操作文件中的内容
'''
文件操作基本流程:打开文件 -> 操作文件(读操作和写操作) -> 关闭文件
'''
# 2.1 打开文件
'''
open(file, mode='r', *, encoding=None) - 以指定的方式打开指定文件
1. file - 需要打开的文件的路径(文件地址) - 字符串格式
1)绝对路径 - 文件在计算机中的全路径(windows电脑从盘名开始写)
2)相对路径 - a.写路径的时候用.开头表示当前目录(当前目录指的是当前代码文件所在的文件夹)
b.写路径的时候用..开头表示当前目录的上层目录
2. mode - 文件打开方式;
作用:a.决定打开文件后是能读还是能写;b.决定操作文件的时候数据的类型是字符串还是二进制
两个作用对应两组值:
1)第一组:决定打开后是读还是写
r(默认值) - 只读;如果文件不存在会报错
w - 只写;打开文件的时候会先清空原文件;如果文件不存在不会报错,并且会自动创建文件,文件夹不存在会报错
a - 只写;打开文件的时候不会清空原文件;如果文件不存在不会报错,并且会自动创建文件,文件夹不存在会报错
2)第二组:决定操作文件的时候数据的类型(str,bytes)
t(默认值) - 字符串类型(操作文件的时候涉及到的数据必须是字符串) - 打开文本文件
b - 二进制类型(操作文件的时候涉及到的数据必须是bytes) - 二进制文件(图片、视频、音频、pdf)只能用b
注意:给mode赋值的时候必须在两组中每一组选择一个值
'rt'、'tr'、'rb'、'br'、'r'
'wt'、'wb'、'tw'、'bw'、'w'
3. encoding - 文本编码方式(只有以t的方式打开文件的时候才考虑给encoding赋值)
不同的文本编码方式决定字符编码在保存的时候采用的字节数(大小)
常用的文本编码方式:
utf-8:ASCII中前128个符号(包括英文符号)单字节,中文符号三字节(所有语言都可以编码)
gbk:英文符号单字节,中文符号双字节(好多国家的语言没有编码)
2)使用原则:
不同时候操作同一个文件采用的编码方式必须一致(不一致可能乱码或报错)
补充:计算机内存单位
8位(b) = 1字节(B)
1kb = 1024字节
1mb = 1024kb
1G = 1024mb
1t = 1024G
malloc(字节数,数据类型) - 申请内存(python中不需要自己申请,系统会根据要保存的数据自己申请)
'''
# 1.文件路径
# 使用绝对路径
open(r'D:\千峰学习资料\就业班课程资料\个人笔记\python语言基础\day13-文件操作\files\data.txt')
# 使用相对路径
open('./files/data.txt')
# 相对路径如果是以'./'开头的,'./'可以省略
open('files/data.txt')
# 相对路径,若要打开文件和当前文件在一个文件夹下面直接写文件名就可以
open('./demo.py')
# 使用..对应的相对路径
open(r'../day13-文件操作/files/data.txt')
# 2.打开方式
# 1)r是只读的
# f = open('files/data.txt', 'r')
# f.read()
# f.write('xy') # 报错 io.UnsupportedOperation: not writable
# 2)w是只写的,并且会清空原文件
# f = open('files/data.txt', 'w')
# f.read() # 报错 io.UnsupportedOperation: not readable
# f.write('xy')
# 3)a是只写的,并且不会清空原文件
# f = open('files/data.txt', 'a')
# f.write('abc')
# f.read() # 报错 io.UnsupportedOperation: not readable
# 4)读的方式打开不存在的文件会报错,写的方式打开不存在的文件不会报错并且会自动创建文件
# open('files/data1.txt', 'r') # 报错 FileNotFoundError: [Errno 2] No such file or directory: 'files/data1.txt'
open('files/data2.txt', 'w')
open('files/data3.txt', 'a')
# 5)t是字符串
f = open('files/data.txt', 'rt')
result = f.read()
print(type(result),result) # <class 'str'> xyabcabc
f = open('files/data.txt', 'at')
# f.write(29) # 报错
# 6)b是二进制
f = open('files/data.txt', 'rb')
result = f.read()
print(type(result), result) # <class 'bytes'> b'xyabcabc'
f = open('files/data.txt', 'ab')
f.write(b'abc')
f.write(bytes('abc', encoding='utf-8'))
# 3.编码方式(默认是采用系统的编码方式,pycharm默认是utf-8)
# f = open('files/data4.txt', 'w', encoding='gbk')
# f.write('aaa数据实际上是bbb')
# f = open('files/data4.txt', 'w', encoding='utf-8')
# f.write('aaa数据实际上是bbb')
# f = open('files/data4.txt', 'r', encoding='gbk')
# print(f.read())
# f = open('files/data4.txt', 'r', encoding='utf-8')
# print(f.read()) # 报错,编码错误 UnicodeDecodeError: 'utf-8' codec can't decode byte 0xca in position 3: invalid continuation byte
# f = open('files/data5.txt', encoding='utf-8')
# print(f.read())
print('------------------世界上最帅气的分割线---------------------')
# 2.2 操作文件
'''
1)文件读操作
文件对象.read() - 从读写位置开始,读到文件结尾(读写位置默认在文件开头)
文件对象.readline() - 从读写位置开始,读到一行结束
2)文件写操作
文件对象.write(数据) - 将指定数据写入文件
'''
f = open('files/test1.txt', 'rt', encoding='utf-8')
result = f.read()
print(result)
print('------------------世界上最帅气的分割线---------------------')
# 进行一次读操作后,读写位置移动到最后,此时再想读可以移动读写位置到文件开头
f.seek(0)
result = f.read()
print(result)
print('------------------世界上最帅气的分割线---------------------')
f.seek(0)
# print(f.readline())
# print(f.readline())
print('------------------世界上最帅气的分割线---------------------')
# 练习:读test1中的内容,一行一行的读,读完为止
f = open('files/test1.txt', 'rt', encoding='utf-8')
# while True:
# word = f.readline()
# if word:
# print(word, end='')
# else:
# break
while True:
word = f.readline()
if not word:
break
print(word, end='')
# 只有打开的时候会清空内容
f2 = open('files/data.txt', 'w', encoding='utf-8')
f2.write('你好 小李')
f2.write(str([10, 20, 30, 40]))
# 2.3 关闭文件
# 文件对象.close()
f2.close()
#f2.write('123') # 报错 ValueError: I/O operation on closed file.
# 操作完需要手动关闭
# f = open('files/data.txt')
print('------------------世界上最帅气的分割线---------------------')
# 代码段操作完后自动关闭
with open('files/data.txt', 'r', encoding='utf-8') as f:
print(f.read())
# f.read() # 报错,文件已经关闭了
二、数据持久化
# 1.对程序中的数据做持久化的步骤
'''
第1步:确定持久化对象(到底哪些数据需要持久化)
第2步:创建文件,并且确定文件初始内容
第3步:在程序中需要这个数据的时候从文件中读数据
第4步:在数据发生改变以后需要将最新的数据写入文件中
'''
# 练习1:写程序打印程序被执行的次数
#
# # 持久化对象:已经运行过的次数
# f1 = open('files/count.txt', 'r', encoding='utf-8')
# num = int(f1.read())
# num += 1
# # 保存最新的次数
# f1 = open('files/count.txt', 'w', encoding='utf-8')
# f1.write(str(num))
# print(num)
# f1.close()
# 练习2:写程序添加学生信息,并且打印已经添加过的所有学生
'''
第一次运行:
请输入学生姓名:小明
小明
第二次运行:
请输入学生姓名:小花
小明 小花
'''
# f2 = open('files/students.txt', 'a', encoding='utf-8')
# name = input('请输入学生姓名:')
# f2.write(name + ' ')
#
# f2 = open('files/students.txt', 'r', encoding='utf-8')
# print(f2.read())
#
# f2.close()
# 老师讲解
# # 持久化对象:所有添加的学生的名字
# name = input('请输入学生姓名:')
# # 将新添加的学生保存到文件中
# f2 = open('files/students.txt', 'a', encoding='utf-8')
# f2.write(name + ' ')
# f2.close()
# # 打印所有已经添加过的学生
# f2 = open('files/students.txt', 'r', encoding='utf-8')
# print(f2.read())
# f2.close()
# 补充:eval函数
# eval(字符串) - 获取字符串引号中的结果,使用前提,引号里面的数据必须是个有效数据
# str(100) -> '100'
# eval('100') -> 100
# 练习2:写程序添加学生信息,并且打印已经添加过的所有学生
'''
第一次运行:
请输入学生姓名:小明
请输入学生的成绩:89
[{'name': '小明', 'score': 89}]
第二次运行:
请输入学生姓名:小花
请输入学生的成绩:100
[{'name': '小明', 'score': 89},{'name': '小花', 'score': 100}]
'''
# name = input('请输入学生姓名:')
# score = int(input('请输入学生的成绩:'))
#
# f3 = open('files/student_message.txt', 'r', encoding='utf-8')
# student = eval(f3.read())
# student.append({'name': name, 'score': score})
#
# f3 = open('files/student_message.txt', 'w', encoding='utf-8')
# f3.write(str(student))
# f3.close()
#
# f3 = open('files/student_message.txt', 'r', encoding='utf-8')
# print(eval(f3.read()))
# f3.close()
# 老师讲解
# 持久化对象:所有已经添加过的学生信息
name = input('请输入学生姓名:')
score = int(input('请输入学生的成绩:'))
# 获取之前已经添加过的所有学生
f = open('files/students2.txt', 'r', encoding='utf-8')
all_student = eval(f.read()) #type:list
f.close()
# 添加这次添加的学生
all_student.append({'name': name, 'score': score})
print(all_student)
# 更新文件
f = open('files/students2.txt', 'w', encoding='utf-8')
f.write(str(all_student))