文件内指针的移动单位一般是Bytes,但也有特殊情况:t模式下的read(n)操作,n代表文件指针移动的单位字符个数。
# 读出二进制解码得到的字符串:hello你好
# 硬盘: 0101010101101010101011010101010
# 只有t模式下read(n),这个n代表的字符个数——————特殊情况
# UTF-8标准下,一个英文字符是一个字节Byte,一个中文字符代表三个字节,3Bytes。
with open(‘a.txt‘,mode=‘rt‘,encoding=‘utf-8‘) as f:
data=f.read(6)
print(f.tell()) # 8 = 5+3
print(data) # hello你
了解:硬盘容量的本之就是能够存多少二进制数bit
# 字节换算
8bit=>1Byte
1024Byte = 1KB
1024KB=1MB
1024MB=1GB
1024GB=1TB
# 硬盘换算
1GB=1024*1024*8
b模式打开文本文件、字符的解码、utf-8
with open("a.txt",mode="rb") as f:
data = f.read(8)
print(type(data)) # <class ‘bytes‘>
print(len(data)) # 8
print(data.decode("utf-8")) # hello你
b模式打开文本文件、字符的解码、gbk
with open("a.txt",mode="rb") as f:
data = f.read(7)
print(type(data)) # <class ‘bytes‘>
print(len(data)) # 7
print(data.decode("gbk")) # hello鍝 由于文本文件是使用utf-8编码的,所以使用gbk用来解码无法解除正确的字符,utf-8模式下,一个中文字符对应三个字节,而gbk模式对应2个字节,所以出现错误字符。
截断,是一种写操作
with open(r"C:\Users\ccf\PycharmProjects\S15\day010\a.txt", mode="r+t", encoding="utf-8") as f:
f.truncate(7) # hello? hello哈 有8个字节,第七个字节截断会出现乱码
f.seek(x,y)
x代表的是移动的字节个数
y代表的模式:
1) 0:代表参照物是文件开头,可以在t模式和b模块下使用
2) 1:代表参照物是当前位置,只能在b模式下用
3) 2:代表参照物是文件末尾,,只能在b模式下用
with open(‘d.txt‘, mode=‘rt‘, encoding=‘utf-8‘) as f: # 哈hello
f.read(3) # 3个字符
print(f.tell()) # 5个字节
f.seek(3, 0) # 0模式,3字节
print(f.tell()) # 指针从开头移动3个字节
with open(‘d.txt‘, mode=‘rb‘) as f: # 哈hello
f.read(1) # 1字节
print(f.tell()) # 1字节
f.seek(2,1) # 2字节,从一字节位置往后
print(f.tell()) # 3字节
with open(‘d.txt‘, mode=‘rb‘) as f:
# f.seek(3333, 2)
# print(f.tell()) # 14+3333=3347
# f.seek(-3, 2)
# print(f.tell())
f.seek(0, 2) # 快速将指针移动到文件末尾
print(f.tell())
案例:日志监控
tail -f access.log
import time
with open(r"/day10/代码/access.log", mode="rb") as f:
f.seek(0, 2) # 快速将指针移动到文件末尾
while True:
line = f.readline() # 每次读取一行数据
if len(line) == 0:
time.sleep(0.1) # 停顿时间0.1s
else:
print(line.decode(‘utf-8‘),end=‘‘)
# 文件a.txt内容如下
张一蛋 山东 179 49 12344234523
李二蛋 河北 163 57 13913453521
王全蛋 山西 153 62 18651433422
# 执行操作
with open(‘a.txt‘,mode=‘r+t‘,encoding=‘utf-8‘) as f:
f.seek(9)
f.write(‘<妇女主任>‘)
# 文件修改后的内容如下
张一蛋<妇女主任> 179 49 12344234523
李二蛋 河北 163 57 13913453521
王全蛋 山西 153 62 18651433422
# 强调:
# 1、硬盘空间是无法修改的,硬盘中数据的更新都是用新内容覆盖旧内容
# 2、内存中的数据是可以修改的
# 实现思路:
1) 将文件内容发一次性全部读入内存,
2) 然后在内存中修改完毕
3) 最后再覆盖写回原文件
# 优点: 不费硬盘,在文件修改过程中同一份数据只有一份
# 缺点: 费内存,会过多地占用内存
with open(‘db.txt‘,mode=‘rt‘,encoding=‘utf-8‘) as f:
data=f.read()
with open(‘db.txt‘,mode=‘wt‘,encoding=‘utf-8‘) as f:
f.write(data.replace(‘K‘,‘S‘))
# 实现思路:
1) 以读的方式打开原文件,以写的方式打开一个临时文件,
2) 一行行读取原文件内容,修改
3) 修改完后写入临时文件...,删掉原文件,将临时文件重命名原文件名
# 优点: 不费内存,不会占用过多的内存
# 缺点: 费硬盘,在文件修改过程中同一份数据存了两份
import os
with open(‘db.txt‘,mode=‘rt‘,encoding=‘utf-8‘) as read_f, open(‘.db.txt.swap‘,mode=‘wt‘,encoding=‘utf-8‘) as wrife_f:
for line in read_f:
wrife_f.write(line.replace(‘S‘,‘K‘))
os.remove(‘db.txt‘)
os.rename(‘.db.txt.swap‘,‘db.txt‘)
原文:https://www.cnblogs.com/huluhuluwa/p/13109874.html