文件操作
针对磁盘中的文件的读写。文件I (input) / O (ouput)
-
文件操作步骤:
- 1- 打发文件 (open)
- 2- 读写文件 (write / read)
- 3- 关闭文件 (close)
1. 文件的基础操作
'''
open() 打开文件
格式:open(文件的路径、打开的方式、[字符集])
参数1: 文件路径
路径 url 统一资源定位符
相对路径:
绝对路径:
参数2: 打开的方式
基础模式: w r x a
- w模式: write 写入
如果文件不存在,则创建这个文件
文件如果存在,则打开这个文件,并且清空文件内容
文件打开后,文件的指针在文件的最前面
参数 encoding 可选参数: 设置文件的字符集
如果是二进制的文件时,不需要设置字符集
encoding='utf-8'
'''
# 1.打开文件,创建一个文件对象
fp = open('./1.txt','w',encoding='utf-8')
# 2.写入内容
# 使用文件对象,调用write() 方法,写入内容
fp.write('hello world')
# 3.关闭文件
# 使用文件对象,调用close() 方法,关闭文件
fp.close()
2. 文件打开的模式详解
'''
打开的方式
1. 基础模式: w r x a
- w模式: write 写入
如果文件不存在,则创建这个文件
文件如果存在,则打开这个文件,并且清空文件内容
文件打开后,文件的指针在文件的最前面
- r 模式: read 读取
如果文件不存在,则报错
文件如果存在,则打开文件
文件指针在文件的最前面
- X 模式: xor 异或模式
如果文件不存在,则创建这个文件
如果文件已存在,则报错(防止覆盖)
文件的指针在文件的最前面
- a 模式: append 追加模式
如果文件不存在,则创建这个文件
文件如果存在,则打开文件,追加内容(和 w 模式的区别)
文件指针在文件的最后面
2. 扩展模式:
b b模式 bytes 二进制
+ +模式 plus 增强模式(可读可写)
3. 文件模式的组合:
w,r,a,x
wb,rb,ab,xb
w+,r+,a+,x+
wb+,rb+,ab+,xb+
'''
# 1.打开文件,创建一个文件对象
# 如果使用r 模式读取一个不存在的文件,则报错 FileNotFoundError
# 如果使用x 模式读取一个已存在的文件,则报错 FileExistsError
fp = open('./1.txt','r',encoding='utf-8') # 不存在则报错 FileNotFoundError
# 2. 读取文件内容
# 使用文件对象,调用read() 方法,读取内容
res = fp.read()
print(res) # hello world
3. 文件操作的步骤和方式
# 1.打开文件
fp = open('./1.txt','a',encoding='utf-8')
# 2.写入文件
fp.write('\n你好')
# 3.关闭文件
fp.close()
# 读取文件操作
# 1.打开文件
fp = open('./1.txt','r',encoding='utf-8')
# 2.读取文件
res = fp.read()
# 3.关闭文件
fp.close()
print(res)
# 文件操作的 高级写法
'''
with open(文件路径,打开模式) as 变量
变量.操作()
不需要写关闭
'''
# r+ 可读可写
# w+ 可读可写,但是打开文件后直接清空了文件
# a+ 追加写入,并且可读,注意指针在内容最后面
# x+ 异或
with open('./3.txt','r+',encoding='utf-8') as fp:
# 设置指针的位置
fp.seek(10,0) # 设置当前指针位置
fp.write('cc')
fp.seek(0) # 指针到起始位置 seek(0)
res = fp.read()
print(res)
4. 文件操作的相关函数
open()
打开文件
格式: open(文件路径,,打开的方式,[字符集])write()
写入内容
格式:文件对象.write(字符串)writelines()
写入容器类型数据
格式:文件对象.write(容器类型数据)
注意:容器类型数据中的元素也必须是可写入的字符串类型
# 写入相关函数
# vars = 5322 # int类型无法写入
# vars = ['hello','world']
vars = {'name':'xiao','age':'22'}
with open('./4.txt','w+',encoding='utf-8') as fp:
# fp.write(vars) # 只能写入字符串类型数据
fp.writelines(vars) # 可以写入容器类型数据,注意容器中的元素也必须是字符串类
read()
读取内容
格式:文件对象.read() 从当前指针位置读到最后
格式:文件对象.read(读取的字节数) 可以读取指定长度的字符readline()
读取一行
格式:文件对象.readline() 一次读取一行
格式:文件对象.readline(读取的字节数) 一次读取一行中的指定字节数readlines()
读取所有行
格式:文件对象.readlines() 读取所有行,每一行作为一个元素,返回一个列表
格式:文件对象.readlines(6) 按行读取,可以设置读取的字节数,设置的字节数不足一行按一行算
# 读取相关函数
with open('./5.txt','r',encoding='utf-8') as fp1:
# fp1.seek(2) # 设置指针的位置,跳过2个字节
# res = fp1.read() # 默认从当前指针读取到最后
# res = fp1.read(3) # 设置读取的字节长度
res = fp1.readline() # 一次只读取一行
print(res) # 床前明月光
res = fp1.readline(3) # 读取当前行中的指定字节数
print(res) # 疑是地
res = fp1.readlines() # 一次读取多行数据,每一行作为一个元素,返回一个列表
print(res) # ['上霜\n', '举头望明月\n', '低头思故乡']
seek()
设置文件指针
with open('./5.txt','r+',encoding='utf-8') as fp2:
# a+ 模式,指针默认在文件末尾,所以直接读是读取不到内容的
# fp2.seek(0) # 把文件指针移到开头
fp2.seek(10)
fp2.seek(0,2) # 把文件指针设置到文件的末尾
fp2.write('\n000000')
res = fp2.read()
truncate()
截断文件内容
with open('./5.txt','r+',encoding='utf-8') as fp3:
res = fp3.truncate(5)
# 默认从文件的首行的首个字符开始截断,截断的长度为 size 个字节数
# size 如果为0,则从当前位置直接截断到最后
print(fp3.read()) # abcde
5. 文件操作的小案例
用户的注册和登录
- 注册
'''
注册功能
1.需要用户名、密码以及确认密码
2.注册时如果用户名以及存在,则不能再注册
'''
# 定义数据变量,存放以及注册的用户信息
userlist = [] # 存放用户名
pwdlist = [] # 存放密码
# 读取所有注册信息(不用r模式,文件不存在时会报错)
with open('user.txt','a+',encoding='utf-8') as fp:
# 使用a+模式打开文件,调整指针位置在起始位置
fp.seek(0)
res = fp.readlines()
for i in res:
r = i.strip() # strip()去除两侧的空白和换行 pao:123\n ==> pao:123
arr = r.split(':') # ['pao', '123']
userlist.append(arr[0]) # 存放用户名
pwdlist.append(arr[1]) # 存放密码
# 注册
def register():
# 定义一个变量,用于控制外循环
state = True
# 循环执行,用户名输入操作
while state:
# 用户名
username = input('欢迎注册,请输入用户名:')
# 判断用户名是否已存在
if username in userlist:
print('当前用户名已存在,请更换用户名')
else:
# 循环输入密码,当两次密码正确时,才退出循环
while True:
# 密码(检测密码长度不低于3)
pwd = input('请输入密码')
if len(pwd) >= 3:
# 确认密码(检测与密码一致)
rpwd = input('请输入确认密码')
if pwd == rpwd:
# 用户名和密码都正确,则可以写入文件
# 打开文件,写入数据
with open('./user.txt','a+',encoding='utf-8') as fp:
fp.write(f'{username}:{pwd}\n')
print(f'注册成功,用户名:{username}')
# 结束循环
# 结束外循环,更改状态
state = False
# 结束内循环
break
else:
# 两次密码不一致,则重新输入密码
print('两次密码不一致,请重新输入')
else:
print('密码格式不正确')
register()
- 登录
'''
登录功能
1.需要使用以及注册过的用户信息登录
2,密码输入错误3次,则锁定账户信息(不能登录)
'''
# 老师的做法
# 定义数据变量,存放以及注册的用户信息
userlist = [] # 存放用户名
pwdlist = [] # 存放密码
blacklist = [] # 存放黑名单用户名
# 读取所有注册信息(不用r模式,文件不存在时会报错)
with open('user.txt','a+',encoding='utf-8') as fp:
# 使用a+模式打开文件,调整指针位置在起始位置
fp.seek(0)
res = fp.readlines()
for i in res:
r = i.strip() # strip()去除两侧的空白和换行 pao:123\n ==> pao:123
arr = r.split(':') # ['pao', '123']
userlist.append(arr[0]) # 存放用户名
pwdlist.append(arr[1]) # 存放密码
# 获取黑名单
with open('./black.txt','a+',encoding='utf-8') as fp:
fp.seek(0)
res = fp.readlines()
for i in res:
blacklist.append(i.strip())
# 封装函数实现登录功能:
def login():
# 定义变量,控制用户登录外循环
isLogin = True
# 定义变量,用户输入密码错误次数的检测
errNum = 3
# 循环执行用户的登录
while isLogin:
# 获取用户名
username = input('欢迎登录,请输入用户名')
# 检测用户是否存在
if username in userlist:
# 判断是否在黑名单?
if username in blacklist:
print('当前用户属于锁定状态,无法登陆!')
isLogin = False
else:
# 定义循环,执行密码输入
while True:
# 让用户输入密码
pwd = input('欢迎登录,请输入您的密码')
# 检测密码是否正确
# 获取用户名在用户列表中的索引 (用户名与密码一一对应,索引序号一致)
inx = userlist.index(username)
if pwd == pwdlist[inx]:
print('登录成功!')
# 循环结束
isLogin = False # 结束外循环
break # 结束内循环
else:
# 密码错误,次数减1
errNum -= 1
if errNum == 0:
print('你没有机会了,拜拜!')
# 锁卡,写入黑名单
with open('./black.txt','a+',encoding='utf-8') as fp:
fp.write(username+'\n')
# 结束循环
isLogin = False # 结束外循环
break # 结束内循环
else:
print(f'密码输入错误,请重新输入,还有{errNum}次机会')
else:
# 用户不存在
print('用户输入错误,请重新输入')
login()
- 登录与注册的合并
'''
用户注册与登录功能的合并
'''
userlist = [] # 存放用户名
pwdlist = [] # 存放密码
blacklist = [] # 存放黑名单用户名
# 读取所有数据的方法
def readallusers():
# 读取所有注册信息(不用r模式,文件不存在时会报错)
with open('./user.txt','a+',encoding='utf-8') as fp:
# 使用a+模式打开文件,调整指针位置在起始位置
fp.seek(0)
res = fp.readlines()
for i in res:
r = i.strip() # strip()去除两侧的空白和换行 pao:123\n ==> pao:123
arr = r.split(':') # ['pao', '123']
userlist.append(arr[0]) # 存放用户名
pwdlist.append(arr[1]) # 存放密码
# 获取黑名单
with open('./black.txt','a+',encoding='utf-8') as fp:
fp.seek(0)
res = fp.readlines()
for i in res:
blacklist.append(i.strip())
# 封装函数实现注册功能:
def register():
# 定义一个变量,用于控制外循环
state = True
# 循环执行,用户名输入操作
while state:
# 用户名
username = input('欢迎注册,请输入用户名:')
# 判断用户名是否已存在
if username in userlist:
print('当前用户名已存在,请更换用户名')
else:
# 循环输入密码,当两次密码正确时,才退出循环
while True:
# 密码(检测密码长度不低于3)
pwd = input('请输入密码')
if len(pwd) >= 3:
# 确认密码(检测与密码一致)
rpwd = input('请输入确认密码')
if pwd == rpwd:
# 用户名和密码都正确,则可以写入文件
# 打开文件,写入数据
with open('./user.txt','a+',encoding='utf-8') as fp:
fp.write(f'{username}:{pwd}\n')
print(f'注册成功,用户名:{username}')
# 结束循环
# 结束外循环,更改状态
state = False
# 结束内循环
break
else:
# 两次密码不一致,则重新输入密码
print('两次密码不一致,请重新输入')
else:
print('密码格式不正确')
# 封装函数实现登录功能:
def login():
# 定义变量,控制用户登录外循环
isLogin = True
# 定义变量,用户输入密码错误次数的检测
errNum = 3
# 循环执行用户的登录
while isLogin:
# 获取用户名
username = input('欢迎登录,请输入用户名')
# 检测用户是否存在
if username in userlist:
# 判断是否在黑名单?
if username in blacklist:
print('当前用户属于锁定状态,无法登陆!')
isLogin = False
else:
# 定义循环,执行密码输入
while True:
# 让用户输入密码
pwd = input('欢迎登录,请输入您的密码')
# 检测密码是否正确
# 获取用户名在用户列表中的索引 (用户名与密码一一对应,索引序号一致)
inx = userlist.index(username)
if pwd == pwdlist[inx]:
print('登录成功!')
# 循环结束
isLogin = False # 结束外循环
break # 结束内循环
else:
# 密码错误,次数减1
errNum -= 1
if errNum == 0:
print('你没有机会了,拜拜!')
# 锁卡,写入黑名单
with open('./black.txt','a+',encoding='utf-8') as fp:
fp.write(username+'\n')
# 结束循环
isLogin = False # 结束外循环
break # 结束内循环
else:
print(f'密码输入错误,请重新输入,还有{errNum}次机会')
else:
# 用户不存在
print('用户输入错误,请重新输入')
# 判断当前的脚本是否作为一个主进程在执行
if __name__ == '__main__':
# 这里的代码只有在使用python解析器直接运行时才会执行
# 如果当前的脚本作为一个模块,被其他文件导入后使用,那么这个地方的代码不会执行,适合写当前脚本中的一些测试
while True:
# 调用初始化方法,写在while中,因为注册成功或失败,userlist和blacklist需要进行更新
readallusers()
vars = '''
*******************************
** 登录(0) 注册(1) 退出(任意)**
*******************************
'''
print(vars)
# 用户选择对应操作
num = input('请输入要进行的操作(序号)')
if num == '0':
login()
elif num == '1':
register()
else:
break