今日内容概要
- 文件操作
- 文件读写模式
- 文件诸多方法
- 文件内光标的移动
- 文件内光标的移动实战演练
- 计算机硬盘存取数据的原理
- 文件内容修改
1.文件操作
1.文件的概念
操作系统给用户操作硬盘的快捷方式
比如我们双击打开一个文件,就是把硬盘中存储的数据加载到内存中
ctrl+s(保存) 就是将内存中的数据存储到电脑硬盘中
2.代码打开文件的两种方式:
1.变量名 = open('文件路径','读/写模式',encoding = 'utf8')
2.with open('文件路径','读/写模式',encoding = 'utf8') as 变量名:
3.
'''
文件路径的\符号容易与Python内方法冲突,所以我们在编写文件路径的时候最好在字符串引号前面添加一个r,让路径转义,这样可以避免我们误操作,导致python报错
'''
2.文件读写模式
1.文件读写模式分为:
'r'
'w'
'a'
1.'r' 只读模式, 如果文件路径不存在,会直接报错
with open('b.txt','r',encoding='utf8') as c:
print(c.read())
如果文件存在,就会读取文件内的内容
with open('a.txt','r',encoding='utf8') as d:
print(d.read())
2.'w'只写模式, 如果文件路径不存在,那么会创建一份新的文件
with open('b.txt','w',encoding='utf8') as c:
c.write('我是天下第一大帅哥')
'''
如果需要编写多行,需要自己添加换行符,并且在后续文件对比时也要注意换行符的存在
w模式每次打开文件会先清空文件内容,然后在进行编写
'''
3.'a' 只追加模式,只在文件末尾添加数据,如果文件路径不存在,那么会创建一份新的文件
with open('a.txt','a',encoding = 'utf8') as b:
b.write('是的你真帅')
4.pass
pass 在python中的作业是为了保持语法结构的完整性
if 条件:
pass (跳过,什么都不做)
可以跳过需要执行子代码的条件/循环/...等
3.文件操作模式:
1.文件操作模式
1. t 文本模式
如上述文件读写操作都是以文本模式进行的操作,我们写读写模式时把t隐藏掉了
完整的写完应该是:
with open('a.txt','rt',encoding='utf8') as b:
在读写模式后面加上t,代表我们所使用的文件操作模式
2. b 二进制模式
二进制模式的写法为:
with open('a.txt','rb') as c:
二进制模式,在'r','w','a'模式操作方式与文本模式操作方式一致
4.文件操作方法
1.read()
只读方法,一次性读取文件内所有内容,并且光标/指针停留在内容末尾。
文件内容比较多时,如果计算机内存不够读取文件内的数据,就会爆内存
read()方法中可以填数字参数
例:
with open('a.txt','rb') as c:
print(c.read())
with open('a.txt', 'r',encoding='utf8') as d:
print(d.read())
2.readline()
只读一行方法:只读文件中的一行内容,并且光标/指针会停留在第一行内容末尾
with open('a.txt','r',encoding='utf8') as i:
print(i.readline())
print(i.readline())
3.readlines()
读取文件所有内容,并根据每行进行分割
with open('a.txt','r',encoding='utf8') as i:
a = i.readlines()
print(a)
print(type(a))
4.readable()
判断文件是否可读,返回布尔值
with open('a.txt','r',encoding='utf8') as i:
print(i.readable())
5.write()
写入数据
with open('a.txt','w',encoding='utf8') as c:
c.write('天下第一剑神,小白')
6.writable()
判断文件是否可写入内容,返回布尔值
with open('a.txt','w',encoding='utf8') as c:
print(c.writable())
7.writelines()
写入一个列表,列表内可写多行内容,换行需要使用换行符隔开
with open('a.txt','w',encoding='utf8') as c:
c.writelines(["就是牛 1\n", "还是牛 2"])
8.flush()
用来刷新缓冲区的,即将缓冲区中的数据立刻写入文件,同时清空缓冲区,不需要是被动的等待输出缓冲区写入。
相当于ctrl + S 保存功能
9.for循环
for循环也可用于文件读取
在读取文件时就可以一行一行的遍历出来,这样可以避免read()方法内存容纳不下被爆掉
10.文件内光标移动
1.seek()
seek方法可以用于移动文件读取指针/光标到指定位置。
()内参数为:
offset,whence
开始的偏移量 哪里(模式0,1,2)
with open('a.txt','rb') as c:
c.seek(3,0)
print(c.read(6).decode('utf8'))
c.seek(-9,2)
print(c.read(9).decode('utf8'))
whence参数 1,2 模式只支持b(二进制模式)使用,0模式t,b模式都可以使用
2.tell()
tell 方法可以查询当前光标/指针所处位置
a = c.tell()
print(a)
5.文件内光标移动实战操作
光标移动也有实际的应用场景:
import time
with open(r'a.txt', 'rb') as f:
f.seek(0, 2)
while True:
line = f.readline()
if len(line) == 0:
time.sleep(0.5)
else:
print(line.decode('utf8'), end='')
'''
此功能是一个小监控功能,可以读取文件内新录入的内容,并打印出来
'''
6.计算机硬盘修改数据的原理
1.硬盘记录数据的原理
硬盘读写数据我们可以看成在纸上记录数据,当我们需要修改中间位置内容时,就需要重新写字,写过的字不能冲中间分开它们
2.硬盘删除数据的原理
不是直接拿橡皮擦擦除纸上内容,而是改变它的状态,等待后续的文字内容覆盖它
简单的说,硬盘在保存文件时,一般会按照“簇”的形式将数据进行保存,至于保存的文件默认会记录在文件分配表中。而硬盘删除文件时,系统也不会把它所存储的文件全部清空,而是将之前在各个分配表中的“簇”标记为空显示。文件分配表里面还有哪个“簇”没有使用,后期所存储的数据也就会存入该簇中。所以在数据重新写入之前,这些删除的文件依然会存在之前所在的“簇”中,直到新数据的写入,覆盖原有数据。
我们一旦覆盖了原来已经改变状态了的区域,那么我们就无法在进行恢复了,此数据一定会丢失,无法在恢复
7.文件内容修改
1.文件内部修改信息其实就由上述计算机硬盘修改数据的原理一致
方式1:
方式2:
'''先在另外一个地方写入内容 然后将源文件删除 将新文件命名成源文件'''
import os
with open('a.txt', 'r', encoding='utf8') as read_f, \
open('.a.txt.swap', 'w', encoding='utf-8') as write_f:
for line in read_f:
write_f.write(line.replace('tony', 'kevinSB'))
os.remove('a.txt')
os.rename('.a.txt.swap', 'a.txt')
8.练习题及答案
1.编写简易版本的拷贝工具
自己输入想要拷贝的数据路径 自己输入拷贝到哪个地方的目标路径
任何类型数据皆可拷贝
ps:个别电脑C盘文件由于权限问题可能无法拷贝 换其他盘尝试即可
solution:1
location = input('请输入您想要拷贝的数据路径>>>>>>:')
target_location = input('请输入您的目标数据路径>>>>>>:')
with open(r'{}'.format(location),'rb') as data:
data1 = data.read()
location1 = location.split('\\')
for b in location1:
if '.' in b:
data2 = b
with open(r'{}\{}'.format(target_location,data2),'wb') as target_data:
target_data.write(data1)
print('拷贝成功哦,就是牛')
solution:2
want_file_path = input('请输入您想要拷贝的文件路径>>>>>:')
target_file_path = input('请输入您的目标路径>>>>>>:')
with open(r'{}'.format(want_file_path), 'rb') as file_read, open(r'{}'.format(target_file_path), 'wb') as file_write:
for data in file_read:
file_write.write(data)
2.利用文件充当数据库编写用户登录、注册功能
文件名称:userinfo.txt
基础要求:
用户注册功能>>>:文件内添加用户数据(用户名、密码等)
用户登录功能>>>:读取文件内用户数据做校验
ps:上述功能只需要实现一次就算过关(单用户) 文件内始终就一个用户信息
while True:
print('欢迎光临随风登录系统'
'1.用户注册:'
'2.用户登录')
choice = input('请输入您想要选择功能>>>>>>:')
if choice.strip() == '1':
print('用户注册')
with open('userinfo.txt','w',encoding='utf8') as data:
username = input('请输入您的用户名>>>>>:')
password = input('请输入您的密码>>>>>:')
data.writelines(f'{username},{password}\n')
print(f'{username}注册成功')
if choice.strip() == '2':
print('用户登录')
target_username = input('请输入用户名>>>>>:')
target_password = input('请输入密码>>>>>>:')
with open('userinfo.txt', 'r', encoding='utf8') as data1:
b = data1.readlines()
for x in b:
if target_username in x and target_password in x:
print(f'{target_username}登录成功')
else:
print('用户名或密码输入错误')
拔高要求:
用户可以连续注册
用户可以多账号切换登录(多用户) 文件内有多个用户信息
ps:思考多用户数据情况下如何组织文件内数据结构较为简单
提示:本质其实就是昨天作业的第二道题 只不过数据库由数据类型变成文件
solution:1
while True:
print('欢迎光临随风登录系统'
'1.用户注册:'
'2.用户登录')
choice = input('请输入您想要选择功能>>>>>>:')
if choice.strip() == '1':
print('用户注册')
with open('userinfo.txt','a',encoding='utf8') as data:
username = input('请输入您的用户名>>>>>:')
password = input('请输入您的密码>>>>>:')
data.writelines(f'{username},{password}\n')
print(f'{username}注册成功')
if choice.strip() == '2':
print('用户登录')
target_username = input('请输入用户名>>>>>:')
target_password = input('请输入密码>>>>>>:')
with open('userinfo.txt', 'r', encoding='utf8') as data1:
b = data1.readlines()
for x in b:
if target_username in x and target_password in x:
print(f'{target_username}登录成功')
else:
print('用户名或密码输入错误')
solution:2
while True:
print('请您根据提示输入指令\n'
'1.用户注册'
'2.用户登录'
'3.退出程序(Q)')
choice = input('请输入您想执行的功能编号>>>>>:').strip()
if choice == '1':
username = input('请输入您想要注册的用户名>>>>>:').strip()
with open(r'userinfo.txt', 'r', encoding='utf8') as data_read:
for real_data in data_read:
if username == real_data:
print('用户名已经存在,请重新注册')
break
else:
password = input('请输入你想设置的密码>>>>>:').strip()
with open(r'userinfo.txt', 'w', encoding='utf8') as data_file:
data_file.write(f'{username}|{password}')
print(f'恭喜{username}注册成功,允许登录')
elif choice == '2':
username = input('请输入您的用户名>>>>>:').strip()
password = input('请输入您的密码>>>>>:').strip()
with open(r'userinfo.txt', 'r', encoding='utf8') as data_read:
for real_data in data_read:
real_username, real_password = real_data.split('|')
if real_password == password and real_username == username:
print('登录成功')
break
else:
print('请输入正确的用户名或密码')
elif choice.upper() == 'Q':
print('程序结束')
break
else:
print('请输入正确编号')
注意:此功能并不完善,solution2 必须是在已经有userinfo.txt文件并且里面有数据才可允许
而solution1 里面无法判断用户名是否重复!!!