今日内容回顾
文件处理
#应用程序运行过程中产生的数据最先都是存放于内存中的,若想永久保存下来,必须保存于硬盘,应用程序若想操作硬件必须通过操作系统,而文件就是造作系统提供给应用程序来操作硬盘的虚拟概念,用户或应用程序对文件的操作,就是向操作系统发起调用,然后由操作系统完成对硬盘的具体操作
文件操作的基本流程
打开文件,由应用程序向操作系统发起系统调用open(...),操作系统打开该文件对应一块硬盘空间,并返回一个文件对象赋值给一个变量f
#open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True):
f=open('a.txt','r',encoding='utf-8')#默认打开模式为r
调用文件对象下的读/写方法,会被操作系统转换为读/写硬盘的操作
data=f.read
向操作系统发起关闭文件的请求,回收系统资源
f.close()
1.#能够操作哪些类型文件:
.txt 没有后缀名的文件
2.如何操作文件
三步法:
1.打开文件
2.读或写文件
3.关闭文件
文件的路径:相对路径,绝对路径
1.打开文件
f=open(r'C:\Users\Dsik\Desktop\test.txt','r')#打开文件
2.读文件
print(f.read())#读取文件内容
3.关闭文件
print(f.close())#关闭文件
资源回收与with上下文管理
打开一个文件包含两部分,应用程序的变量f和操作系统打开的文件,在操作完毕一个文件时,必须把与该文件的这两部分资源全部回收
f.close() #回收操作系统打开的文件资源
del f #回收应用程序的变量
第二种方法操作文件
with上下文管理器打开文件
as:起别名
它的特点就在于:能够自动关闭文件
with open(r'C:\Users\Dsik\Desktop\test.txt','w',encoding='utf-8') as a:
print(a.write('genglianwen')) #写入文件会返回一个整型且写入文件会覆盖之前的内容
with open(r'C:\Users\Dsik\Desktop\test.txt','r',encoding='utf-8') as a:
print(a.read(5))#read可以通过索引取第几个,从1开始
with open(r'C:\Users\Dsik\Desktop\test.txt','r',encoding='utf-8') as a:
#print(a.read())#read可以通过索引取第几个,从1开始,读取所有数据
#print(a.readline())#一行一行读
print(a.readlines())#读出来的数据以列表的形式展现,且包含换行符
文件的读写模式
'''
语法风格:
open(文件路径,读写模式,字符编码)
文件路径:必须写
读写模式:必须写
字符编码:可选
'''
读写模式:
r(只读:只能读数据,不能写)
w(只写:只能写,不能读)
a(append:在原来的基础之上在添加新的内容)
1.只读模式
r #该文件必须已存在
r+ #可读可写,该文件必须已存在,写为追加在文件内容末尾
rb #表示以二进制方式读取文件,该文件必须已存在
f=open('b.txt','r',encoding='utf-8')
print(f.read())#No such file or directory: 'b.txt'
with open('a.txt','r',encoding='utf-8') as a:
print(a.read())# [Errno 2] No such file or directory: 'a.txt'
with open(r'C:\Users\Dsik\Desktop\test.txt','r+',encoding='utf-8') as a:
print(a.read())
with open(r'C:\Users\Dsik\Desktop\test.txt','r+',encoding='utf-8') as a:
print(a.write('ccd'))#每次写内容都会在原来内容后面追加
print(a.read())
2.写模式
w #只写,打开即默认创建一个新文件,如果文件已存在,则覆盖(原始内容覆盖)
w+ #写读,打开创建新文件并写入数据,如果文件已存在,则覆盖写,w+在打开文件时就会先将文件内容清空。
wb #表示以二进制写方式打开,只能写文件,如果文件不存在,创建该文件,如果文件存在,覆盖写
with open(r'C:\Users\Dsik\Desktop\test.txt','w',encoding='utf-8') as a:
print(a.write('ccd'))#默认只能写
print(a.read())#不能读
3.追加模式
追加模式:当路径不存在的时候,也会新建一个文件,它是追加写,不覆盖原来的内容
#with open('c.txt','a',encoding='utf-8') as a:
a.write('hello world')
a.write('yes')
#hello worldhello worldhello worldhello worldyes
读写操作相关的方法
1.读系列
with open('c.txt','r',encoding='utf-8') as f:
# print(f.read())# 一次性读取所有行
# print(f.readline()) # 只读取一行数据
# print(f.readlines())# 读取所有数据以列表的形式呈现
print(f.readable())#判断文件是否可读
2.写系列
lines=['hello','world']
with open('b.txt','w') as i:
#print(i.write('abc'))#如果文件不存在,就创建并写入内容,如果存在则覆盖内容
print(i.writelines(lines))#接收一个字符串序列作为参数,将每个字符串写入文件中,每个字符串都会以换行符结尾
文件的读操作优化
with open('b.txt','r',encoding='utf-8') as a:
#print(a.read())
#文件支持for循环,可以循环取值
for i in a:
print(i)
print(a.flush())#把数据从内存中立刻刷到磁盘
'''当读取数据比较小的时候,其实是在缓冲区,当数据够多的时候,它会刷到磁盘'''
#一次性读取文件的所有数据有什么问题:
当数据比较多的时候,会出现内存溢出,这种情况坚决不能出现
如何优化以上操作:
#一点一点的读取数据然后把数据刷到硬盘中
文件的二进制操作模式
1.文本模式
t:text
rwa =====> rt wt at
'''
with open('userinfo.txt','r',encoding='utf-8') as f:
文本文件默认就是操作字符串,文本
特征:
encoding参数必须指定
读取的所有数据都是以字符串为单位
t模式只能够读取文本或者字符模式
'''
二进制模式
b模式:binary
with open('userinfo.txt','rb') as f:
b模式中b不能省略 ------> rb wb ab
特征:
encoding='utf-8'参数不能够指定
读取的数据全部以字节为单位
二进制模式可以读取任意类型的文件
课堂练习题
# 1. 写一个简易版本的注册和登录功能
# 只需要实现一次注册和登录即可------------->单用户的注册
# 注册
# 注册的用户数据需要写在文件里面
# 登录
# 比较的用户名和密码要从文件中读取
user_name = input("注册账号:").strip()
user_ps = input("密码:").strip()
user_data = '%s|%s' % (user_name, user_ps)
with open('b.txt', 'w', encoding='utf-8') as s:
#写数据
s.write(user_data)
print('成功')
#登录
username=input("用户名:").strip()
password=input("密码:").strip()
with open('b.txt','r',encoding='utf-8') as u:
#读取的数据存放在变量中
user_data=u.read()
# 切分内容
us,ps=user_data.strip().split('|')
#比较字符串是否相等
if username == us and password == ps:
print('yes')
else:
print('err')
多用户注册登录功能
多用户的注册功能和多用户数据情况下的登录功能
多用户的注册:
1. 可以在程序不结束的情况下注册多个用户
2. 需要验证用户名不能重复
3. 注册的多用户的用户名和密码如何存储?
while True:
us=input("注册账号:").strip()
ps=input("密码:").strip()
user_data='%s-%s\n'%(us,ps)
flag=False
#看是否user存在,这样写首先b.txt要有内容,否则报错
with open('b.txt','r',encoding='utf-8') as r1:
for line in r1:
#解压赋值
username,password=line.strip().split('-')
if username ==us:
#如果存在,flag就变值
flag=True
break
if not flag: #取反
with open('b.txt','a',encoding='utf-8') as w1:
w1.write(user_data)
else:
print('user exist')
'''整合代码'''
while True:
print('1.注册账号'.center(30,' '))
print('2.登录账号'.center(30,' '))
print('3.按q退出'.center(30,' '))
x=input('请选择:').strip()
if x=='1':
us=input("注册账号:").strip()
ps=input("密码:").strip()
user_data='%s-%s\n'%(us,ps)
flag=False
#读文件,看是否user存在
with open('b.txt','r',encoding='utf-8') as r1:
for line in r1:
#解压赋值
username,password=line.strip().split('-')
if username ==us:
#如果存在,flag就变值
flag=True
break
if not flag: #取反
with open('b.txt','a',encoding='utf-8') as w1:
w1.write(user_data)
else:
print('user exist')
elif x=='2':
x_name=input('用户名:').strip()
x_pwd=input("密码:").strip()
with open('b.txt','r',encoding='utf-8') as f:
for i in f:
name,pwd=i.strip().split('-')
if x_name == name and pwd == x_pwd:
print('sucess')
break
elif x == '3':
break
作业
写一个简易版本的拷贝功能
1. 代码运行之后输入被拷贝的文件路径
2. 代码运行之后还要在 输入你把此文件拷贝到哪个位置去
#
source_data = input('请输入被copy的文件路径:').strip()
target_data = input('请输入你要copy到哪去的文件路径:').strip()
with open(r'%s'%source_data, 'r') as r1:
with open(r'%s'%target_data, 'w') as w1:
w1.writelines(r1.readlines())
print('拷贝成功')