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,如果不包含,那么返回这一行的时间

iOS 文件读写需要在主线程吗 文件读写a_iOS 文件读写需要在主线程吗

代码如下

iOS 文件读写需要在主线程吗 文件读写a_打开文件_02