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')  #文件改名字