python 文件之指针操作

一:文件内指针移动的单位是什么?

读出二进制解码的到的字符串:
只有t模式下,read(n),n是字符个数
with open('a.txt', mode='rt',encoding='utf-8') as f: # 你好呀hello word
    data = f.read(6)
    print(f.tell())  # 12
print(data) # 你好呀hel

b模式下read(n),n是多少个二进制数bit
8bit=>1Byte
1024Byte = 1KB
1024KB=1MB
1024MB=1GB
1024GB=1TB
1GB=1024*1024*8
with open('a.txt',mode='rb') as f:
    data =f.read(6)
    print(f.tell())  # 6
print(data.decode('utf-8'))  # 你好


以b模式读取文件内容
with open('a.txt', mode='rb') as f:
    data = f.read(9)  # 在utf-8编码保存文件一个中文字符占3个byte
    print(type(data))
    print(len(data))
    print(data.decode('utf-8'))

b.txt 文件是以gbk编码保存的文件,底层存的是二进制
gbk编码中文占连个byte
with open('b.txt', mode='rb') as f:  # hello你好
    data = f.read(7)
    print(type(data))
    print(len(data))
print(data.decode('utf-8')) # 报错 你以gbk编码写入文件的,同样都出来,也是gbk编码读出来
print(data.decode('gbk'))

二 主动/单独地控制文件指针移动
f.seek(x,y)
x代表移动的字节个数
y代表模式(0,1,2)b
0:代表指针参照物是文件开头,可以在t模式和b模式下使用
b.txt是以utf-8编码存储到文件中
with open('b.txt', mode='rt', encoding='utf-8') as f:  # 从删库到跑路
    data = f.read(2)
    print(data)  # 从删
    print(f.tell()) # 6

1:代表的是当前位置,只能在b模式下用
c.txt他是utf-8编码存的
with open('c.txt',mode='rb') as f:  # 你好word
    f.read(1)
    print(f.tell())  # 1
    f.seek(2, 1)
    print(f.tell())  # 3
    print(f.read().decode('utf-8'))  # 好word

2:代表的是参照物在文件末尾,只能以b模式下用
with open('d.txt', mode='rb') as f:  # 你好word真难
    f.seek(250, 2)
    print(f.tell())  # 16+250=266
    f.seek(-3, 2)
    print(f.tell())  # 13
    f.seek(0, 2)    # 快速将指针移动到文件末尾(可以用a模式打开也一样
    print(f.tell())  # 16

开发 tailf -f 命令

import time

with open(r'D:\s9\day10\acess.log', mode='rb') as f:
    f.seek(0, 2)
    while True:
        line = f.readline()
        if len(line) == 0:
            time.sleep(1)
        else:
            print(line.decode('utf-8'),end='')

日志生成器
import time
with open('acess.log', mode='at', encoding='utf-8') as f:
    f.write('%s 你这个程序是死循环\n' % (time.strftime('%Y-%m-%d %H:%M:%m')))


文件修改
文件修改都是模拟出来的,实现修改需要借助内存
硬盘数据没有修改的说法,都是用新内容覆盖旧的内容
有两种方式
方式一
1:硬盘中的内容全部读入内存,
2:把内存中的数据一次性修改完毕
3:把内存中修改完成的结果覆盖会原文件
with open('f.txt', mode='rb') as f_read:  # 你好word真难
    data = f_read.read().decode('utf-8')
    res = data.replace('word', '世界')
    print(res)

with open('f.txt', mode='wb') as f_write:
    f_write.write(res.encode('utf-8'))
缺点:浪费内存,有可能文件过大,撑爆内存
优点:不费硬盘空间,数据只存一份


方式二
1:把硬盘内容全部读入内存
2:在内存中把内容一次性修改完毕,临时存储到硬盘中
3:让后把临时文件重新命名,源文件删除掉

import os
with open('f.txt', mode='rt',encoding='utf-8') as read_f,\
        open(".f.txt.swap",mode='wt',encoding='utf-8') as write_f:  # 你好世界真难
    for line in read_f:
        write_f.write(line.replace("word",'世界'))

os.remove('f.txt')
os.rename('.f.txt.swap', 'f.txt')
优点:省内存空间,内存同一时刻只有文件的一行内容
缺点:浪费硬盘文件,在修改过程中会存放两份数据