zoukankan      html  css  js  c++  java
  • 文件处理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')
  • 相关阅读:
    list()
    Python 数据类型转换
    设计模式 — 代理模式(静态代理、动态代理、Cglib代理) 转载
    java线程池实现原理
    HashMap深度解析(转载) jdk1.7
    Java Serializable 序列化和反序列化 (转载)
    Java遍历HashMap并修改(remove)(转载)
    Java中的break,continue关于标签的用法(转载)
    遍历List过程中删除操作报java.util.ConcurrentModificationException错误
    java Date时间的各种转换方式和Mysql存时间类型字段的分析
  • 原文地址:https://www.cnblogs.com/bk134/p/12508023.html
Copyright © 2011-2022 走看看