python学习笔记03:文件操作
文件操作分三步:
1)打开文件:文件在当前目录下直接写文件名,若在其他路径,写绝对路径(反斜杠可以用来转义,使用r可以让反斜杠不发生转义);字符集需要指定utf-8,若有中文会乱码
2)读/写文件
3)关闭文件
1.文件打开模式
r:只读模式(默认)
w:只写模式【文件不存在创建,文件存在则删除内容】
a:追加模式,可写不可读【文件不存在则创建,文件存在则追加内容】
r+:可读可写【默认文件指针在最开始,若有内容,写会覆盖原来内容,文件不存在会报错】
w+:可写可读【会清空内容,文件不存则创建】
a+:可读可写【默认文件指针在末尾,写文件时在末尾追加,读文件时文件指针移动到最前面,文件不存在不会报错】
b表示处理二进制文件【其他类型(图片,视频,音频文件)】:rb wb ab rb+ wb+ ab+
2.读文件
1 f1 = open('文本.txt', encoding='utf-8') #以只读方式打开一个文件,r可以不写 2 result1 = f1.readline() #读文件,一次只读取一行 3 print('result1结果:', result1) 4 f1.close() #关闭文件 5 6 f2 = open('文本.txt', encoding='utf-8') 7 result2 = f2.read() #读文件,获取文件里面的全部内容 8 print('result2结果:', result2) 9 f2.close() 10 11 f3 = open('文本.txt', encoding='utf-8') 12 result3 = f3.readlines() #读文件,读取文件里面的所有内容,返回的是一个list,每行的内容是list的一个元素 13 print('result3结果:', result3) 14 f3.close()
3.写文件
1 f = open('文本.txt', 'w', encoding='utf-8') 2 f.write('123\n') #写文件时清空以前的内容。若不存在的文件,会创建新文件 3 f.close() 4 5 f = open('文本.txt', 'w', encoding='utf-8') 6 l = ['1234\n', '234\n'] 7 f.writelines(l) #写文件时清空以前的内容,可以传list,循环list 8 f.close() 9 10 f = open('文本.txt', 'w', encoding='utf-8') 11 l = ['1234\n', '234\n'] 12 for i in l: 13 f.write(i) #write只能传字符串 14 f.close()
4.处理大文件
read()和readlines()方法操作文件的话,会先把文件所有内容读到内存中,内存数据一多,非常卡,高效的操作,就是读一行操作一行,读过的内容就从内存中释放
# 处理大文件时 f = open('文本.txt', 'r', encoding='utf-8') for line in f: #line就是每行文件的内容,循环读,读完一行释放一行的内存 print(line)
5.监控日志小练习
1 # 监控日志文件,IP超过50次报警 2 # 分析: 3 # 1.监控日志,一直运行,死循环,每分钟读一次文件 4 # 2.第一次运行,读取文件所有内容,从文件内容里面找到获取到IP地址,以及每个IP地址出现的次数 5 # 3.记住当前指针的位置,下次从这个位置开始读 6 # 4.判断每个IP出现的次数,如果大于50次,那么就发短信报警 7 # 5.等待60s,继续重复上面的操作,读文件,获取内容 8 9 import time 10 point = 0#定义point,0代表最前面的位置 11 while True:#死循环 12 f = open(r'C:\Users\zx\Desktop\access.log', encoding='utf-8')#只读模式r可以省略 13 f.seek(point)#移动指针到哪个位置 14 ip_list = {}#定义字典{'ip':2} 15 for line in f:#循环文件 16 ip = line.split()[0]#分割成list,取下标为0的元素 17 if ip not in ip_list: 18 ip_list[ip] = 1#第一次出现,次数=1 19 else: 20 ip_list[ip]+=1#不是第一次出现,出现次数+1 21 point = f.tell()#记住当前指针的位置 22 f.close()#关闭文件 23 for ip in ip_list:#如果ip在ip_list里 24 count = ip_list.get(ip)#找出ip对应的值 25 if count >= 50:#找到ip>50 26 print('ip地址【%s】有问题,请注意!' % ip) 27 time.sleep(60)#等待60s
6.修改文件
1)简单直接
(适用于修改小文件,不适用于大文件)
1 # 1)读取文件所有内容 2 # 2)替换replace内容 3 # 3)清空文件 4 # 4)把新的内容写进去 5 with open('数据.txt', 'r+', encoding='utf-8') as f: #用with打开文件会自动关闭该文件 6 content = f.read() 7 new_content = content.replace('100', '1000000') 8 f.seek(0) 9 f.truncate() #清空文件 10 f.write(new_content) 11 f.flush() #不管缓冲区是否满,立即刷新缓冲区的内容,写到磁盘里 12 # 若写入文件后,文件没有更新,因为写文件(内存写到磁盘),为了不让内存和磁盘频繁交互,中间有个缓冲区,缓冲区满了以后在往磁盘里写,没更新说明缓冲区没有满 13 # 读文件时,先从磁盘上读,读完搁到内存,再给cpu,速度:cpu>内存>磁盘
2)用两个文件操作
(适用于大文件)
1 # 1)r模式打开a文件,w模式打开b文件 2 # 2)逐行读取a文件的内容,读完之后替换内容 3 # 3)把替换完的内容写到b文件里面 4 # 4)把a文件删掉,把b文件的名字改成a文件 5 import os 6 with open('数据.txt', encoding='utf-8') as f1, open('数据2.txt', 'w', encoding='utf-8') as f2: 7 for line in f1: 8 new_line = line.replace('4', '44444') 9 f2.write(new_line) 10 os.remove('数据.txt') #删除f1文件(若写到with里面有可能认为文件还在使用,会报错) 11 os.rename('数据2.txt', '数据.txt') #文件改名字