文件处理b模式和指针

一丶文件处理的b模式

  b模式都是以二进制为单位

  1.b模式的使用

 with open('1.mp4',mode='rb') as f:
     data=f.read()
     print(type(data)) # 输出结果为:<class 'bytes'>

with open(r'f.txt',mode='wb') as f:
     f.write('你好hello'.encode('utf-8'))
     f.write('哈哈哈'.encode('gbk'))# 在b模式下写入文件的只能是bytes类型

  总结:

    1、在操作纯文本文件方面t模式帮我们省去了编码与解码的环节,b模式则需要手动编码与解码,所以此时t模式更为方便
    2、针对非文本文件(如图片、视频、音频等)只能使用b模式

  

# 文件拷贝工具
src_file=input('源文件路径>>: ').strip()
dst_file=input('源文件路径>>: ').strip()
with open(r'{}'.format(src_file),mode='rb') as f1,
    open(r'{}'.format(dst_file),mode='wb') as f2:
    # res=f1.read() # 内存占用过大
    # f2.write(res)

    for line in f1:
        f2.write(line)
文件拷贝工具

  

    

  2.操作文件的方法  

# 读操作
# 1.f.read()一次性读出所有内容,读完内容指针在结尾
with open('a.txt','rt',encoding='utf-8') as f:
    print(f.read())

# 2.f.readline()一次只读一行,读完一行光标移动到下一行头部
with open('a.txt','rt',encoding='utf-8') as f:
    res1=f.readline()
    res2=f.readline()
    print(res2)

# 3.f.readlines()读取每行内容放到列表当中,在一次性读出
    with open(r'a.txt',mode='rt',encoding='utf-8') as f:
        res=f.readlines()
        print(res)
# 强调:
# f.read()与f.readlines()都是将内容一次性读入内存,如果内容过大会导致内存溢出,若还想将内容全读入内存
读操作   

  

# 循环读取文件
    # 方式一:以行为单位读,当一行内容过长时会导致一次性读入内容的数据量过大
    with open('a.txt','rt',encoding='utf-8') as f:
        for line in f:
            print(line)

    # 方式二
    with open('a.txt','rb') as f:
        while True:
            res=f.read(1024) # 每次只读取1024字符
            if len(res) == 0:
                break
            print(len(res))
循环读取文件
# 写相关操作
#f.write()  f.writelines()将列表内的元素依次写入
with open('a.txt','wt',encoding='utf-8') as f:
    f.write('1111
222
3333
') #针对文本模式的写要自己写换行符
    l = ['11111
', '2222', '3333', 4444]
    # for line in l:
    #     f.write(line)
    f.writelines(l)#writelines完成了上面for循环的功能


with open('a.txt','wb') as f:
    l = [
        '1111aaa1
'.encode('utf-8'),
        '222bb2'.encode('utf-8'),
        '33eee33'.encode('utf-8')
    ]

    # 补充1:如果是纯英文字符,可以直接加前缀b得到bytes类型
    #     l = [
    #         b'1111aaa1
',
    #         b'222bb2',
    #         b'33eee33'
    #     ]

    # 补充2:'上'.encode('utf-8') 等同于bytes('上',encoding='utf-8')
    #     l = [
    #         bytes('上啊',encoding='utf-8'),
    #         bytes('冲呀',encoding='utf-8'),
    #         bytes('小垃圾们',encoding='utf-8'),
    #     ]
    f.writelines(l)

# f.flush 将要写的内容马上存入硬盘
# with open('h.txt', mode='wt',encoding='utf-8') as f:
#     f.write('哈')
#     f.flush()
写相关操作
with open('h.txt', mode='wt',encoding='utf-8') as f:
    print(f.readable())# 文件是否可读
    print(f.writable())# 文件是否可读
    print(f.encoding)# 如果文件打开模式为b,则没有该属性
    print(f.name)
print(f.closed)# 文件是否关闭
了解操作

  

二丶控制内指针的移动

'''指针移动的单位都是以bytes/字节为单位
只有一种情况下特殊:t模式下的read(n),n代表的是字符个数'''
with open('a.txt',mode='rt',encoding='utf-8') as f:
     data=f.read(3) # 读取3个字符

with open('a.txt',mode='rb') as f:
     data=f.read(3) # 读取3个Bytes


# f.seek(指针移动的字节数,模式控制):
# 0: 默认的模式,参照物是文件开头位置
f.seek(9,0) # 9
f.seek(3,0) # 3
# 1: 参照物是当前指针所在位置
f.seek(9,1) # 9
f.seek(3,1) # 12
# 2: 参照物是文件末尾位置,应该倒着移动
f.seek(-9,2) # 3
f.seek(-3,2) # 9


# 强调:其中0模式可以在t或者b模式使用,而1跟2模式只能在b模式下用

# f.tell() # 获取文件指针当前位置

  2.1 0模式详解

with open('a.txt',mode='rb') as f:
    f.seek(4,0) # 4
    print(f.tell())
    res=f.read()
    print(res.decode('utf-8'))

  2.2 1模式详解

with open('a.txt',mode='rb') as f:
    f.seek(3, 1) 
    print(f.tell()) #3
    f.seek(4, 1)
    print(f.tell()) #7

  2.3 2模式的详解

with open('a.txt',mode='rb') as f:
   f.seek(0,
2) print(f.tell()) # 9 f.seek(-3,2) # 参照文件末尾往前移动了3个字节 print(f.read().decode('utf-8')) #

   2.4  f.seek的应用(tail -f accsee.log程序讲解)

# 追写文件内容的程序test.py
with open(r'access.log', 'at', encoding='utf-8') as f:
    f.write('202003111112 egon转账200w
')
    
# 监测追写内容的程序tail.py
import time
with open(r'access.log', 'rb') as f:
    f.seek(0, 2)
    while True:
        line = f.readline()
        if len(line) == 0:
            time.sleep(0.3)
        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、内存中的数据是可以修改的

  3.1 文件修改方式一

# 实现思路:将文件内容发一次性全部读入内存,然后在内存中修改完毕后再覆盖写回原文件
# 优点: 在文件修改过程中同一份数据只有一份
# 缺点: 会过多地占用内存
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('kevin','SB'))

  3.2 文件修改方式二

# 实现思路:以读的方式打开原文件,以写的方式打开一个临时文件,一行行读取原文件内容,修改完后写入临时文件...,删掉原文件,将临时文件重命名原文件名
# 优点: 不会占用过多的内存
# 缺点: 在文件修改过程中同一份数据存了两份
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('SB','kevin'))

os.remove('db.txt')
os.rename('.db.txt.swap','db.txt')
原文地址:https://www.cnblogs.com/bk134/p/12508023.html