Day08 文件执行

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)

Day08 文件执行

 

rb模式下

with open(r'a.text','rb') as f:
    res = f.read(3)  # 代表读取三个字节
    print(res)
    print(res.decode('utf-8'))

Day08 文件执行

 

文件内光标的移动

使用格式: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))

Day08 文件执行

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))

Day08 文件执行

whence:2

with open(r'a.text','rb') as f:  # 1和2必须使用b模式表示
    f.seek(-3,2)  # 2表示文件的末尾,-3表示光标向前三个字符
    print(f.read(1))

Day08 文件执行

 

输出日志和文件内容监测

需求:一个日志文件,当有人添加文件内容时,监测并且输出其内容

添加日志文件内容代码

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'))

Day08 文件执行

 

 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的字符,其他全部删除

Day08 文件执行

 

修改文件内容的两种方法

文件的数据是存放于硬盘上的,因而只存在覆盖、不存在修改这么一说,我们平时看到的修改文件,都是模拟出来的效果,具体的说有两种实现方式:

第一种
  先将数据由硬盘读到内存(读文件)
  在内存中完成修改(字符串的替换)
  再覆盖原来的内容(写文件)

源文件

Day08 文件执行

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)  # 再覆盖原来的内容(写文件)

 Day08 文件执行

优点:任意时间硬盘上只有一个文件 不会占用过多硬盘空间
缺点:当文件过大的情况下,可能会造成内存溢出

 

第二种
  创建一个新文件
  循环读取老文件内容到内存进行修改 将修改好的内容写到新文件中
  将老文件删除 将新文件的名字改成老文件名

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())

Day08 文件执行

优点:内存中始终只有一行内容 不占内存
缺点:再某一时刻硬盘上会同时存在两个文件

上一篇:JavaWeb 黑马2019 day08_HTML&CSS


下一篇:ecshop二次开发常用代码