zoukankan      html  css  js  c++  java
  • 文件的高级应用

    文件的高级应用

    一、可读、可写(不经常用到,了解即可)

    • r+t:可读、可写 r+
    • w+t:可写、可读 w+
    • a+t:可追加、可读 a+
    # r+  r+w
    with open(r'text.txt',mode='r+',encoding='utf-8') as f:
        print(f.readable())
        print(f.writable())
        f.write('嘿嘿嘿')
        
    True
    True    
    
    # w+t w+t
    with open(r'text.txt',mode='w+',encoding='utf-8') as f:
        print(f.readable())
        print(f.writable())
        
    True
    True    
    
    # a+t a+
    with open(r'text.txt','a+',encoding='utf-8') as f:
        print(f.readable())
        print(f.writable())
    True
    True    
    

    二、文件内光标移动

    假设我们需要在文件内容中间的某一行增加内容,如果使用基础的rwa模式实现是非常困难的,因此我们需要对文件内的指针进行移动。

    硬盘上从来没有修改一说,硬盘上只有覆盖,即新内容覆盖老内容。

    在rt模式下,read内的数字,表示的是字符的个数,除此之外,数字表示的都是字节

    with open(r'text.txt','r',encoding='utf-8') as f:
        print(f.read(5))  # 读取了5个字节
    
    今天是一个    
    

    在rb模式下,read内的数字,表示的的是字节的个数。

    with open(r'text.txt','rb') as f:
        res = f.read(12)
        print(res)  # 读取的是12个字节   3个字节表示一个中文字符 
        print(res.decode('utf-8'))  # 将二进制数据解码成utf-8二进制
    
    b'xe4xbbx8axe5xa4xa9xe6x98xafxe4xb8x80'
    今天是一    
    

    1.f.seek(offset,whence) 光标移动

    • offset:相对偏移量 光标移动的位数
    • whence:
      • 0:参照文件的开头,t和b都可以使用
      • 1:参照光标所在的当前位置,只能b使用
      • 2:参照文件的末尾,只能在b模式中使用
    # whence:0
    with open(r'text.txt','rt',encoding='utf-8') as f:
        print(f.read(1))  # 今
        f.seek(6,0)  # 从将光标从文件开头移动6bytes
        print(f.read(1))  # 是 读取一个字符
        # f.seek(4,0)  # 将光标从开头移动了4个字节,由于汉字是由3个字节表示一个字符,所以会报错
        f.seek(0,0)  # 光标从开头移动0个字节,还在开头,
        print(f.read(1))  # 读取一个字符
        f.seek(6,0)  # 
        print(f.read())
    # whence:1
    with open(r'text.txt','rb') as f:
        print(f.read(3).decode('utf-8'))  # 读取3个字节并用utf-8解码,(今)
        f.seek(3,1)  # 将指针从当前位置移动3个字节,
        print(f.read(1))  # 读取一个字节
        f.seek(6,0)  # 将指针从文件开头移动6个字节,即2个字符
        print(f.read(3))  # 读取3个字节
        f.seek(4,0)  # 将指针从文件开头移动4个字节,
        print(f.read(2))  # 读取2个字节
        
    # whence:3
    with open(r'text.txt','rb') as f:
        print(f.read())  # 读取文件内所有的字节
        f.seek(-9,2)  # 指针从末尾向前移动9个字节
        print(f.read().decode('utf-8'))  # 读取字节并解码成utf-8二进制
        
    with open(r'text.txt','r+',encoding='utf-8') as f:
        f.seek(3,0)
        f.write('时')  # 在第一个字符后面,写入一个字符,会将原来的字符覆盖掉
    
    今时是一个好日子
    今天是一个好日子
    今天是一个好日子
    今天是一个好日子
    今天是一个好日子
    今天是一个好日子
    今天是一个好日子
    今天是一个好日子    
    

    2.f.tell(int):查看光标移动了多少位

    with open(r'text.txt','r+',encoding='utf-8') as f:
        f.seek(18,0)
        print(f.tell())
    18    
    

    3.f.truncate(int):截断文件

    接收字节的长度(保留0~6字节数,后面的全部删除)

    truncate(n)是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate()要在r+或a或a+等模式下测试效果。它的参照物永远是文件头。并且teuncate()不加参数,相当于清空文件。

    with open(r'text.txt','a',encoding='utf-8') as f:
        f.truncate(12)  # (12)接收的字节长度
        # 保留0-12字节数,后面的全部删除(截断)
    

    三、写日志、检测文件内容

    # 写日志.py
    import time
    res = time.strftime('%Y-%m-%d %X')
    
    with open(r'text.txt','a',encoding='utf-8') as f:
        f.write(f'{res} egon给jason发了一亿的工资
    ')
    
    
    # 检测文件内容
    with open(r'text.txt','rb') as f:
        f.seek(0,2)  # 将光标移动到末尾
        while True:
            res = f.readline()  # 每次读取光标后面的一行
    
            # print(f.tell())  # 光标移动的字节数
    
            if res:  # 存在(即检测到新添加的内容)
                print(f'新增的内容:{res.decode("utf-8")}')  # 打印
            # else:
            #     print('暂无其他人操作该文件')
    
    

    四、修改内容

    由于硬盘上从来没有修改一说,硬盘上只有覆盖,即新内容覆盖老内容。那我们如何修改文件呢?

    方法一:

    • 现将数据由硬盘读到内存(读取文件)
    • 在内存中完成修改(字符串的替换)
    • 再覆盖原来的内容(写文件)
    with open(r'text.txt','r',encoding='utf-8') as fr:
        data = fr.read()
        print(data)
        # print(type(data))
    
    with open(r'text.txt','w',encoding='utf-8') as fw:
        res = data.replace('egon','nick')
        fw.write(res)
    
    
    • 优点:任意时间硬盘上只有一个文件,不会占用过多硬盘空间
    • 缺点:当文件过大的情况下,可能会造成内存溢出。

    方法二:

    • 创建一个新文件
    • 循环读取老文件内容到内存进行修改,将修改好的内容写到新文件中
    • 将老文件删除,将新文件的名字改为老文件。
    import os
    with open(r'text.txt','r',encoding='utf-8') as fr,
    open(r'text.swap','a',encoding='utf-8') as fw:
        for line in fr:  # 将文件内容一行行读取
            new_line = line.replace('nick','egon')  # 对文件的每一行替换
            fw.write(new_line)  # 写入新文件
    
    os.remove('text.txt')  # 移除文件
    os.rename('text.swap','text.txt')  # 重命名文件
    
    
    Never,Never,Never give up.
  • 相关阅读:
    设计模式13---设计模式之观察者模式(Observer)(行为型)
    codeforces 166C Median
    HDU 1176 免费馅饼
    老鸟的Python新手教程
    setsockopt()使用方法(參数具体说明)
    RelativeLayout经常使用属性介绍
    java多线程模拟生产者消费者问题,公司面试常常问的题。。。
    JAVA实现HTTPserver端
    进程间通信_03命名管道
    expdp&impdp
  • 原文地址:https://www.cnblogs.com/zuihoudebieli/p/11160921.html
Copyright © 2011-2022 走看看