day11
一.文件的打开模式
(1).控制文件读写操作的模式
r:只读(默认的):在文件不存在时则报错,文件存在时文件指针跳到文件开头
f = open('a.txt',mode='rt',encoding='utf-8')
res = f.read()
print(res)
# print(f.readable()) # 是否可读
# print(f.writable()) # 是否可写
f.close()
w:只写:文件不存在则创建空文件,文件存在则清空,文件指针跳到文件开头
f = open('b.txt',mode='wt',encoding='utf-8')
f.write('你好啊哈哈哈\n')
f.write('hello1\n')
f.write('hello2\n')
f.close()
a:只追加写:文件不存在时则创建空文件,文件存在时也不会清空,文件指针跳到文件末尾
f = open('c.txt',mode='at',encoding='utf-8')
f.write('jason:777\n')
f.write('jjj:666\n')
f.close()
总结:w与a的异同:
相同点:在打开了文件不关闭的情况下,连续地写入,新的内容永远跟在老内容之后
不同点:重新打开文件,w会清空老的内容,而a模式会保留老的内容并且指针跳到文件末尾
案例1:注册功能
name = input('your name: ').strip()
# 做合法性校验:
# 1.如果输入的用户名包含特殊字符^$&..让用户重新输入
# 2.如果输入的用户名已经存在也重新输入
pwd = input('your password: ').strip()
# 做合法性校验
# 1.密码长度
# 2.如果密码包含特殊字符则重新输入
f = open('user.txt',mode='at',encoding='utf-8')
f.write('%s:%s\n' %(name,pwd))
f.close()
案例2:登录功能
inp_name = input('your name: ').strip()
inp_pwd = input('your pwd: ').strip()
f = open('user.txt',mode='rt',encoding='utf-8')
for line in f:
user,pwd=line.strip().split(':')
if inp_name == user and inp_pwd == pwd:
print('login successful')
break
else:
print('user or password error')
f.close()
(2).控制文件读写内容的模式
t(默认):读写都是以str字符串为单位,一定要指定encoding
f = open('a.txt',mode='rt',encoding='utf-8')
f.read()
f.close()
b:读写都是以bytes为单位,一定不能指定encoding参数
f = open('a.txt',mode='rb')
data = f.read()
print(data,type(data))
print(data.decode('utf-8'))
f.close()
f = open('d.txt',mode='wb')
f.write('egon'.encode("utf-8"))
f.close()
案例:文件拷贝程序
old_path = input('源文件路径: ').strip()
new_path = input('目标文件路径: ').strip()
with open(r'%s' % old_path,mode='rb')as f,open(r'%s' % new_path,mode='wb')as t:
for line in f:
t.write(line)
with 上下文管理
省去了f.close()的步骤
with open()as f1,open() as f2:
f1.read()
补充知识(rwa/tb)
tb必须和rwa联用
+必须与rwa联用:r+,w+,a+ / r+b , w+b, a+b
二.文件操作的其他方法
读相关方法
read:读取所有文件内容,执行完该操作后,指针移动到文件末尾
readline:一行一行的读取文件内容,读取一行内容,光标移动到第二行行首
readlines:读取多行内容存到列表中
with open('user.txt',mode='rt',encoding='utf-8')as f:
# line1 = f.read()
# line2 = f.read()
# line3 = f.read()
# print(line1)
# print(line2)
# print(line3)
# 读取到列表中
# 方式一
lines = []
for line in f:
lines.append(line)
# 方式二
lines = f.readlines()
print(lines)
写相关方法:
writelines:将内容是字符串的可迭代性数据写入文件中
with open('a.txt',mode='wt',encoding='utf-8')as f:
lines = ['111\n','222\n','333\n']
for line in lines:
f.write(line)
# f.writelines(lines)
# f.writelines('hello')
了解:
f.flush:立刻将文件内容从内存刷到硬盘
f.name:获取的是打开文件的路径
with open(r'D:\python全栈15期\day11\a.txt',mode='wt',encoding='utf-8') as f:
# print(f.txt.name) # 取的是打开文件的路径
# print(f.txt.closed)
for i in range(100):
f.write("%s\n" %i)
f.flush()
f.truncate(n)
三.控制文件内指针移动
只有一种特殊情况,t模式下的read(n),代表的是n个字符,此外代表的全都是字节
with open('f.txt',mode='rt',encoding='utf-8')as f:
data = f.read(6) # 6个字符
print(data)
with open('f.txt',mode='rb')as f:
# data = f.read(6) # 6个字节
data = f.read(8) # 8个字节
print(data.decode('utf-8'))
# f.seek(n,模式) # n代表的移动的字节个数
模式:
0模式:参照文件的开头开始移动
(只有0模式可以在t模式下使用,1和2模式只能在b模式下使用)
with open('f.txt',mode='rt',encoding='utf-8')as f:
f.seek(5,0)
print(f.tell)
print(f.read())
print(f.tell())
print('='*100)
f.seek(0,0)
print(f.read())
1模式:参照指针当前所在的位置
with open('f.txt',mode='rb') as f:
f.seek(3,1)
f.seek(3,1)
print(f.tell())
# f.seek(2,1)
f.seek(5,0)
print(f.read().decode('utf-8'))
2模式:参照文件末尾的位置
with open('f.txt',mode='rb') as f:
f.seek(3,2) # 2模式下指针在末尾,前面数字3是光标向右移了3位
f.seek(-3,2) # 2模式下指针在末尾,前面数字-3是光标向左移了3位
# print(f.tell()) # tell返回的是当前光标左侧的所有字节数
print(f.read().decode('utf-8'))
tell:返回当前光标左侧所有的字节数
truncate:把要截取的字符串提取出来,然后清空内容将提取的字符串重新写入文件中(括号内是字节数)
# f.truncate(n)从文件开头往后数n个字节保留下来,其余全部删除
# f.truncate()从文件开头往后数指针当前所在的位置,其余全部删除
with open('f.txt',mode='ab') as f:
# f.truncate(3)
# f.seek(-3,2)
f.truncate()
模拟程序记录日志的功能
检测程序运行
import time
with open('access.log', mode='rb') as f:
f.seek(0, 2)
while True:
line = f.readline()
if len(line) == 0:
# 没有读到内容
time.sleep(0.5)
else:
print(line.decode('utf-8'), end='')
写入程序
import time
for i in range(1000):
with open('access.log','a',encoding='utf-8')as f:
t = time.strftime('%Y-%m-%d %H:%M:%S')
strvar = 'egon向刘老师转账%s元'%i
msg = f'{t}{strvar}\n'
f.write(msg)
time.sleep(3)