光标的移动,文件的概念,函数简介
文件内光标的移动(了解)
引言:
with open (r'a.txt','r',encoding = 'utf8') as f:
print(f.read(3))
print(f.read(3))
# read在文本模式下,括号内的数字表示的是读取指定的字符个数,输入的字符如果超过指定的文本,则输出全部文本结束打印
a.txt的内容为: 你吃饭不
tony
jason
jerry
with open(r'a.txt','rb') as f:
print (f.read(9).decode('utf8')) # 你吃饭
print (f.read(1).decode('utf8')) # 报错
# 'utf-8' codec can't decode byte 0xe4 in position 0: unexpected end of data
这是因为read在二进制模式下,括号内的数字表示的是读取指定的字节数,按bytes来提取数据,utf8的中文是三个字节,括号内写了1,相当于把一个汉字给劈开了,那能不报错吗
unicode所有的字符都是用2bytes起步来表示
utf8中文用3bytes来表示,英文用1bytes来表示
控制光标的移动
# seek方法可以控制光标的移动,在文本模式下移动的单位也是字节数
结构:seek(offset,whence)
offset:控制移动的字符数
whence:控制模式
-
控制模式的分类
0模式:相对于文件的开头(让光标先移动到文件开头),支持文本模式和二进制模式
with open(r'a.txt','r',encoding='utf8') as f: f.seek(6,0) print(f.read()) # 输出结果: ''' 饭不 tony jason jerry '''
1模式:先对于当前位置(让光标先停留在当前位置)只支持二进制模式
with open(r'a.txt','rb') as f: f.seek(3) f.seek(6,1) print # 输出结果: ''' 不 tony jason jerry '''
2模式:相对于文件结尾(让光标先移动到文件末尾),只支持二进制模式
with open(r'a.txt','rb') as f: f.seek(3,2) print(f.read().decode('utf8')) # 输出结果为空,因为光标在末尾,后面没有可以打印的东西 with open(r'a.txt','rb') as f: f.seek(-3,2) print(f.read().decode('utf8')) # erry 2模式的字节数可以用负数取值,就是让光标往前移了几个字节数 # 2模式可以用来实时检测文件内是否有新增的内容并打印出来(没有太多的实际意义) with open('access.log', mode='rb') as f: f.seek(0, 2) while True: line = f.readline() if len(line) == 0: # 没有内容 pass else: print(line.decode('utf-8'), end='')
-
tell获取基于文件开头的字节数
with open(r'a.txt', 'rb') as f: f.seek(3, 1) # 基于当前位置 继续往后移动三个字节 print(f.tell()) # 3
文件的修改
引言:
硬盘上的数据有两个状态:占有态与自由态
删除硬盘的数据就是将占有态转换成了自由态,之后如果有新的数据来了并且落到了自由态位置,那么直接覆盖
文件数据在硬盘上其实是刻上去的,不可能从中间再添加新的内容,只能将老的内容转换成自由态,再重新刻新的
"""
实现思路:已读的方式打开原文件,以写的方式打开一个临时文件,一行行读取原文件内容,修改完写入临时文件
删除原文件
优点:不会占用过多的内存
缺点:在文件修改过程中同一份数据存了两份
import os # 模块
"""
import os
with open(r'a.txt','r',encoding='utf8') as read_f, open(r'.a.txt.swap','w',encoding='utf8') as write_w:
for line in read_f:
write_w.write(line.replace('你吃饭不','tuzi'))
os.remove('a.txt') # 删除文件
os.rename('.a.txt.swap','a.txt') # 重命名文件