12.文件操作(下)

本文详细讲解了Python中b模式的文件操作,包括如何以字节为单位读写图片,复制文件的高效方法,以及移动文件指针的技巧。通过实例演示了如何使用b模式进行文件内容追加和替换,并介绍了两种修改文件内容的不同策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.b模式

控制文件读写内容的模式

t模式:
1.读写都是字符串(Unicode)为单位
2.只能针对文本文件
3.必须指定字符编码 即必须指定encoding='utf-8'

b 模式:binary模式 通用所有文件
1.读写都是以bytes为单位
2.可以针对所有文件
3.一定不能指定字符编码 即不能指定encoding='utf-8'

放一张图片tubiao.png到当前目录下,以b模式下,对图片文件进行操作

with open(r'tubiao.png',mode='rb') as f:
    res=f.read()
    print(res)
    print(type(res))
# b'\x89PNG\r\n\x1a\……
#<class 'bytes'>

循环读取文件方式:

方式1:控制每次读取字节数量

with open(r'tubiao.png',mode='rb') as f:
    while True:
        res=f.read(1024)
        if len(res)==0:
            break
        print(res)
        print(len(res))

方式2:每次读取一行数据,

当一行内容过多时,容易一次性读取数据量过大

with open(r'tubiao.png',mode='rb') as f:
    for line in f:
        print(line)

b模式案例:针对所有文件类型的拷贝工具

src_file=input('被拷贝的文件路径>>>').strip()
new_src_file=input('拷贝后的文件路径>>>').strip()
with open(r'{}'.format(src_file),mode='rb') as f1,\
        open(r'{}'.format(new_src_file),mode='wb') as f2:
    # res=f1.read()#内存占用过大
    # f2.write(res)
    for line in f1:
        f2.write(line)

2.文件操作的其他方法

readline 一次读一行

with open(r'db',mode='rt',encoding='utf-8') as f:
    res1=f.readline()
    res2=f.readline()
    print(res1,res2)
    # blll: fsdf
    # dfsdf: fsdf

readlines 一次读出整个文件,并将每一行做一个元素组成列表

with open(r'db',mode='rt',encoding='utf-8') as f:
    res=f.readlines()
    print(res)
    # ['blll:fsdf\n', 'dfsdf:fsdf\n']
read和readlines都是一次将整个文件从硬盘导入内存,谨慎之用。

其余还有一些仅需了解,不常使用的操作方法,不做记录。

3.操作文件指针移动

指针移动的单位都是bytes字节,只有在t模式下的read(n) n代表的单位是字符,一个英文字符一个字节 一个中文字符三个字节。
with open(r'aaa.txt',mode='rt',encoding='utf-8') as f:
    res=f.read(4)
    print(res) #aaa你 读出了前四个字符

1.  f.seek(n,模式):

n指移动的字节个数

模式1:0 以文件开头为参照原点

f.seek(9,0)
f.seek(3,0) #3
只有0模式可以在t模式下使用1、2都要在b模式下使用
#示范 0模式
with open(r'aaa.txt',mode='rb') as f:
    f.seek(3,0)
    print(f.tell())
    res=f.read()
    print(res.decode('utf-8'))
    f.seek(4, 0)
    print(f.tell())
    res = f.read()
    print(res.decode('utf-8'))
    #因为一个汉字占三个字节,如果从中间切割是没办法编码的,会报错
    #UnicodeDecodeError: 'utf-8' codec
    # can't decode byte 0xbd in position 0: invalid start byte

模式2:1 以文件当前位置为参照原点

f.seek(9,1)
f.seek(3,1)#12
#示范 1模式
with open(r'aaa.txt',mode='rb') as f:
    f.seek(9, 1)
    f.seek(3,1)
    print(f.tell())#12
    res=f.read()
    print(res.decode('utf-8'))#空

模式3:2 以文件末尾为参照原点,应该倒着移动

f.seek(-9,2) #3
f.seek(-3,2) #9
#示范 2模式
with open(r'aaa.txt',mode='rb') as f:
    f.seek(-9, 2)
    f.seek(-3,2)
    print(f.tell())#6
    res=f.read()
    print(res.decode('utf-8'))#好

控制指针并不是很常用

2.f.seek()应用案例

模仿Linux的捕捉文件末尾增加内容命令 tail -f access.log (access.log是要监测的文件)

1.目录下新建日志文件access.log

2.实现监测日志文件access.log 的新增内容 的程序代码

#监测日志文件access.log 的新增内容
import time
with open(r'access.log',mode='rb') as f:
    #1.将指针跳到文件末尾
    f.seek(0,2)
    while True:
        line=f.readline()
        if len(line)==0:
            time.sleep(0.3)
        else:
            print(line.decode('utf-8'))

3.新建一个追加日志内容的程序:

with open(r'access.log',mode='at',encoding='utf-8') as f:
    f.write('2021-7-13 bob转账100万给amy\n')

运行2,再运行3,每运行一次3,新增的内容都会被监测程序打印出来。

4.文件修改的两种方式

对于硬盘来说,压根就没有“改”这个功能,都是用新内容完全覆盖旧内容

不要同一行代码,以读(r)的方式打开文件,又以写(w)的方式打开文件,因为那样会直接把文件清空掉。

在当前目录下新建文本文件c.txt,随便添加一些内容,用于演示

方式1:文本编辑器用的就是这种方式

with open(r'c.txt',mode='rt',encoding='utf-8') as f:
    res=f.read()
    data=res.replace('哈哈','呵呵')
    print(data)
# 娃呵呵
# 娃呵呵
# 娃呵呵
with open(r'c.txt',mode='wt',encoding='utf-8') as f:
    f.write(data)

方式2:避免了从硬盘读入内存数据量过大

import os
with open(r'c.txt',mode='rt',encoding='utf-8') as f,\
    open(r'c111.txt',mode='wt',encoding='utf-8') as f1:
    for line in f:
        f1.write(line.replace('呵呵','哈哈'))
os.remove('c.txt')
os.rename('c111.txt','c.txt')

方式1占内存,方式2占硬盘

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值