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