1.控制文件内光标的移动
文件内容的读取
在rt模式下 read内的数字 表示的是字符的个数
除此之外,数字表示的都是字节
如read(3):
1. 当文件打开方式为文本模式时,代表读取3个字符
2. 当文件打开方式为b模式时,代表读取3个字节
rt模式下:
with open(r'a.text','rt',encoding='utf-8') as f: res = f.read(3) # 代表读取三个字符 print(res)
rb模式下
with open(r'a.text','rb') as f: res = f.read(3) # 代表读取三个字节 print(res) print(res.decode('utf-8'))
文件内光标的移动
使用格式:f.seek(offset,whence)
offset:相对偏移量 光标移动的位数,无论哪种模式,都是以bytes为单位移动的
whence:
0:参照文件的开头 t和b都可以使用
1:参照光标所在的当前位置 只能在b模式下用
2:参照文件的末尾 只能在b模式下使用
中文字符使用3个Bytes位表示,英文字符和符号用1个Bytes位表示
whence:0
with open(r'a.text','rt',encoding='utf-8') as f: print(f.read(1)) f.seek(3,0) # 0表示的是文件的开头,3表示移动的Bytes位,3个Bytes表示一个中文字符 print(f.read(1))
whence:1
with open(r'a.text','rb') as f: # 1和2必须使用b模式表示 print(f.readline()) # 当前光标在第一行的末尾 f.seek(2,1) # 1表示当前光标位置,2表示光标向后两个字符 print(f.read(1))
whence:2
with open(r'a.text','rb') as f: # 1和2必须使用b模式表示 f.seek(-3,2) # 2表示文件的末尾,-3表示光标向前三个字符 print(f.read(1))
输出日志和文件内容监测
需求:一个日志文件,当有人添加文件内容时,监测并且输出其内容
添加日志文件内容代码
import time res = time.strftime('%Y-%m-%d %X') # 输出时间 with open(r'a.text','a',encoding='utf-8') as f: f.write('\r{}爸爸的爸爸是爷爷'.format(res)) # 输出内容
监测文件是否变动,变动则输出新增的内容
with open(r'a.text','rb') as f: f.seek(0,2) while True: res = f.readline() if res: print(res.decode('utf-8'))
truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果
with open(r'a.text','r+',encoding='utf-8') as f: f.truncate(12) # 接收的字节的长度 整型 print(f.read()) # 保留0-12Bytes的字符,其他全部删除
修改文件内容的两种方法
文件的数据是存放于硬盘上的,因而只存在覆盖、不存在修改这么一说,我们平时看到的修改文件,都是模拟出来的效果,具体的说有两种实现方式:
第一种
先将数据由硬盘读到内存(读文件)
在内存中完成修改(字符串的替换)
再覆盖原来的内容(写文件)
源文件
with open(r'a.text','rt',encoding='utf-8') as read_f: res = read_f.read() # 先将数据由硬盘读到内存(读文件) with open(r'a.text','w',encoding='utf-8') as write_f: data = res.replace('哈哈哈', '嘻嘻嘻') # 在内存中完成修改(字符串的替换) print(data) write_f.write(data) # 再覆盖原来的内容(写文件)
优点:任意时间硬盘上只有一个文件 不会占用过多硬盘空间
缺点:当文件过大的情况下,可能会造成内存溢出
第二种
创建一个新文件
循环读取老文件内容到内存进行修改 将修改好的内容写到新文件中
将老文件删除 将新文件的名字改成老文件名
import os with open(r'a.text','r',encoding='utf-8') as read1_f,\ open(r'a.swap','a',encoding='utf-8') as write1_f: # 创建一个新文件 for line in read1_f: # 循环读取老文件内容到内存进行修改 将修改好的内容写到新文件中 res1 = line.replace('嘻嘻嘻','哈哈哈') write1_f.write(res1) os.remove('a.text') os.rename('a.swap','a.text') with open(r'a.text','r',encoding='utf-8') as f: # 将老文件删除 将新文件的名字改成老文件名 print(f.read())
优点:内存中始终只有一行内容 不占内存
缺点:再某一时刻硬盘上会同时存在两个文件