8:文件读写
1. 操作文件的流程:
1、有个文件;
2、打开文件:open(filename)。模式:只读 r、写 w、追加模式 a+。默认以只读模式打开;
3、操作文件:进行读操作或写操作;
4、关闭文件:close()。
2. 文件操作模式
-
r 只读,打开的文件不存在,会报错.默认以 r 模式打开。
-
w 只写,会清空原来文件的内容,若文件不存在,会新建。
-
a 追加写,不会清空,若文件不存在,会新建;但是不能读。
-
r+ 读写模式,打开不存在的文件会报错。
-
w+ 写读模式,会把文件内容清空。
-
a+ 追加读模式。文件指针在最后,需要先移动文件指针,才能读到内容。文件不存在的时候不会报错。
-
wb 二进制模式的写,如视频、MP3、图片。
2.1 示例
#以 w 模式打开文件,进行写操作时会把文件中原来的内容覆盖掉
filename = 'user.txt'
f = open(filename, 'w')
f.write('test,123')
f.close()
# a+ 模式打开文件后会把文件指针移动到最后面,如果直接读会读不到东西。
f = open(filename, 'a+')
f.seek(0) #移动文件指针到开始位置
print(f.read()) #获取到文件中的所有内容
f.write('test2,123456\n')
f.flush()
f.close()
3. read() 、 readline()、readlines()
f = open('users.txt', 'a+', encoding='utf-8')
#print('第一次读', f.read()) # 一次性读完所有内容
#print('第二次读', f.read()) # 第二次去读的时候不会读到内容
print(f.readlines()) # 获取到文件所有行, 获取一个列表,每一行是列表中的一个元素
f.readline() # 一行一行的读
4. write()、writelines()
a = ['user1,12344', 'user2,23456']
# 使用 write 方法把列表 a 的内容写进文件里,需要循环
for i in a:
f.write(i+'\n')
# 使用 wrtielines 则不需要。
f.writelines(a)
# 如果是要把一个字符串写进文件直接用 write, 如果是一个 list,就用 writelines。
4. 修改文件内容
第一种方式:简单粗暴的实现方法。
f = open(r'D:\file.txt',encoding='utf-8') #如果文件有中文,需要指定文件的编码方式为 utf-8
# 将文件中的 ‘一点’ 改为 ‘两点’
res = f.read().replace('一点','两点')
f.close()
# 以写的模式打开文件
f = open(r'D:\file.txt',mode='w',encoding='utf-8')
# 将修改后的内容写入文件
f.write(res)
f.flush() #;立即把缓冲区里面的内容,写到磁盘上
f.close()
第二种方式:以 a+ 模式打开,然后实现替换
f = open('file.txt','a+', encoding='utf-8')
f.seek(0)
res = f.read().replace('两点','1点')
f.seek(0)
f.truncate()# 清空文件里面的内容
f.write(res)
f.close()
第三种方式:
import os
f = open('file.txt', encoding='utf-8')
f2 = open('file2.txt', 'w', encoding='utf-8')
for line in f:
new_line = line.replace('你', '我')
f2.write(new_line)
f.close()
f2.close()
os.remove('file.txt') #删除文件
os.rename('file2.txt','file.txt') # 重命名文件
# 代码优化:
# 在打开文件的时候尽量使用 with,这样在使用文件结束的时候会自动判断然关闭文件。不用再使用 close 方法去关闭。
with open('file.txt') as f, open('file2.txt', 'w') as f2:
for line in f:
new_line = line.replace('你', '我')
f2.write(new_line)
os.remove('file.txt') #删除文件
os.rename('file2.txt','file.txt') # 重命名文件
5. 高效处理文件
f = open('users.txt', encoding='utf-8')
文件对象
#第一种方式
while True:
line = f.readline()
if line != '':
print('line:', line)
else:
print('文件内容读完了')
break
# 第二种方式
for line in f:
print(line)
6. 练习
# 需求1:
# 1 要从日志里面找到 1 分钟之内访问超过 200 次的 IP
# 2 每分钟运行一次
# 1.读取文件内容,获取到 Ip 地址
# 2.把每个 IP 地址存起来,使用字典, ip 为 key, 次数为 value
# 3.如果次数超过 200 就加入黑名单
import time
point = 0 #定义文件起始指针位置
while True:
f = open('access.log')
ip_dict = {}
f.seek(point) # 文件指针移动到 point 位置
for line in f:
ip = line.split()[0] # 获取 ip
# 判断 ip 在不在字典里,如果不在,赋值为1;如果已存在,则加1
if ip not in ip_dict:
ip_dict[ip] = 1
else:
ip_dict[ip] += 1
point = f.tell() # tell() 方法用来记录文件指针,下次循环的时候从该位置开始读取
f.close()
for ip,count in ip_dict.items():
if count >= 200:
print('加入黑名单:',ip)
time.sleep(60) # 一分钟之后再读
7. 文件读写与生成器:
需求2:
获取日志文件里包含指定字符 1 的下一行是否包含字符2,如果不包含,那么返回这一行的时间
代码如下