22 文件指针移动

311次阅读
没有评论

共计 2783 个字符,预计需要花费 7 分钟才能阅读完成。

一. 指针移动的单位

  • 除了 t 模式下的 read(n) 中的 n 代表的是字符个数

  • 其余的移动单位都是以 字节为单位

🍉先向文件里写入一串字符
with open(r"test.txt", "w+b")as f:
     f.write("abc 你好 ".encode("utf-8"))

🍉 "t" 模式下的 "read(n)" 读得是字符个数
with open('test.txt',mode='rt',encoding='utf-8') as f:
    res=f.read(5)   # 读 5 个字符
    print(res)      # abc 你

🍉 非 "t" 模式下的 "read(n)" 读得是 Bytes 个数   
with open('test.txt', mode='rb') as f:
    res = f.read(6)                     # 读 6 个 Bytes
    print(res.decode("utf-8"))          # abc 你

二. f.seek() : 偏移量

1. 格式说明

  • f.seek([移动的字节格式],[模式])

2. 三种模式

  • 0 : 参照文件开头移动指针
  • 1 : 参照当前所在的位置移动指针
  • 2: 参照文件末尾位置移动指针

ps : 只有在 0 模式可以在 t 下使用, 12 只能在 b 下使用

with open('test.txt', mode='rt', encoding='utf-8') as f:
    f.seek(3, 0)   # 指针跳到文件开头, 然后向右移动三个字节
    f.seek(3, 1)   # "t" 模式下不支持 "1", 报错
    f.seek(-3, 2)  # "t" 模式下不支持 "2", 报错
  1. f.tell(): 获取当前指针位置

with open('test.txt', mode='rb') as f:
    f.seek(3, 0)      # 指针跳到文件开头, 然后向右移动三个字节
    print(f.tell())   # 3  (光标处于 "abc" 后面)
    f.seek(3, 1)      # 指针在当前停留的位置向右移动三个字节
    print(f.tell())   # 6  (光标处于 "abc 你 " 后面)
    f.seek(-7, 2)     # 指针跳到末尾向左移动七个字节
    print(f.tell())   # 2  (光标处于 "ab" 后面)

三. 模拟 Linux 的 tail -f命令效果

1.tail -f [文件名]

  • 格式 : tail -f [文件名]

  • 功能 : 从末尾实时查看一个文件的新增内容

2. 开始实现

  • 模拟一个日志文件, 里面不断的在写入日志
import time

count = 1
while True:
    with open(r"log.txt","at",encoding="utf-8")as f:
        f.write(f" 这是第 {count} 条日志 \n")
        count +=1
        time.sleep(2)
  • 模拟 tail -f 功能实时监控
import time

with open(r"log.txt","rb")as f:
    f.seek(0,2)
    while 1:
        line = f.read()
        if len(line) == 0:
            time.sleep(0.2)
            continue

        print(line.decode("utf-8"),end="")
        time.sleep(0.3)

3. 使用函数封装 (后一章知识点)

  • 监听任一文件的末尾是否增加数据
import os,time

def tail(file_path):
    if not os.path.isfile(file_path):           #判断文件是否存在
        return " 文件不存在 "
    with open(rf'{file_path}',"rb")as read_f:
        read_f.seek(0,2)
        while True:
            res = read_f.readline()            #判断取出的是否为空
            if len(res) == 0:
                time.sleep(0.2)
                continue
            print(res.decode("utf-8"),end="")
            time.sleep(0.2)

res = tail("H:\Pycharm File\PycharmProjects\python 正课 \day07\log.txt")
print(res)

四. 指针移动小练习

1. 使用 w 模式创建文件, 内容 "abc 你好"

with open(r"testtt.txt", "wt", encoding="utf-8")as f:
    f.write("abc 你好 \n")

2."r +" 模式练习

  • 读全部内容
  • 读出‘你好’
  • 读出‘abc’
  • 把‘abc’覆盖成‘ABC’
  • 把‘你好’覆盖成‘你坏’
with open(r"testtt.txt", "r+", encoding="utf-8")as f:
    print(f.read())   # abc 你好

    f.seek(3, 0)
    print(f.tell())   # 3
    print(f.read())  # 你好

    f.seek(0, 0)
    print(f.tell())   # 0
    print(f.read(3))  # abc

    f.seek(0, 0)
    print(f.tell())   # 0
    f.write("ABC")  
    f.seek(0, 0)
    print(f.read())   # ABC 你好

    f.seek(6, 0)
    print(f.tell())  # 6
    f.write(" 坏 ")
    f.seek(0, 0)
    print(f.read(5)) # abc 你坏

3."w+b" 模式练习

  • 读全部内容
  • 读出‘你好’
  • 读出‘abc’
  • 读出 'c', 再读出’好‘
  • 把‘c’覆盖成’C‘
  • 把‘好’覆盖层’坏‘
🍉先写一串字符进文件
with open(r"testtt.txt", "w+b")as f:
    f.write("abc 你好 ".encode("utf-8"))

    print(f.read().decode("utf-8"))  # abc 你好

    f.seek(-6, 2)
    print(f.tell())                  # 3
    print(f.read().decode("utf-8"))  # 你好

    f.seek(0, 0)
    print(f.tell())                  # 0
    print(f.read(3).decode("utf-8")) # abc

    f.seek(2, 0)                     # 2
    print(f.tell())
    print(f.read(1).decode("utf-8")) # c
    f.seek(-3, 2)
    print(f.tell())                  # 6
    print(f.read().decode("utf-8"))  # 好

    f.seek(2, 0)
    f.write(b'C')           
    f.seek(0, 0)  
    print(f.read().decode("utf-8"))  # abC 你好

    f.seek(6, 0)
    f.write('坏'.encode("utf-8"))
    f.seek(0, 0)
    print(f.read().decode("utf-8"))  # abC 你坏

4."a + b" 模式练习

🍉"a" 模式下, 不管你的指针跳到了那里, 写入的内容都是在文件末尾
with open(r"testtt.txt", "a+b")as f:
    f.seek(0, 0)
    f.write(b'DDD')
    f.seek(0, 0)
    print(f.read().decode("utf-8"))  #abC 你坏 DDD
正文完
 
shawn
版权声明:本站原创文章,由 shawn 2023-06-16发表,共计2783字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)