day09学习笔记

今日内容概要

文件操作

  • 什么是文件

    文件是操作系统提供给应用程序来操作硬盘的虚拟概念。
    
  • 为何要用文件

    读写文件就是在读写用硬盘,我们对文件的读写操作都会被操作系统转换成硬盘的操作
    
    应用程序--------->>> 文件对象,文件句柄
    操作系统--------->>> 文件
    硬件------------->>> 硬盘
    
  • 如何用文件

    1.控制文件读写操作的模式
    r(默认):只读
    w:只写
    a:只追加写
    2.控制文件读写内容的模式
    t(默认):读写都是以字符串为单位,只适用于文件,文件必须指定encoding参数
    b:读写都是以Bytes为单位的,适用于所有文件,一定不能指定encoding
    
  • r模式

    # r 只读模式:在文件不存在会报错,文件存在文件内指针直接跳到文件开头
    with open ('a.txt', mode='rt',encoding='utf8' ) as f:
        res = f.read() # 
    
  • w模式

    # w 只写模式:在文件不存在会新建空文档,文件存在时会清空文件,文件指针跑到文件开头
    with open('b.txt',mode='wt',encoding='utf8') as f:
        f.write('你好\n')
        f.write('我好\n')
    # 注意: w模式,在打开文件不关的情况下,联系写入,新写的内容永远跟在后面
    
  • a模式

    # a 只追写模式,如果文件不存在则创建空文档,文件存在不会清空,文件指针处于文件末尾
    with open('c.txt',mode='at',encoding='utf8') as f:
        f.write('4444')
        f.write('5555')
        f.write('6666')
    
    
  • 操作文件的方法

    # 读 
    .read()  # 读取所有文件内容,执行完该操作后,文件指针会移动到文件末尾
    .readline()  # 读取一行内容,光标移动到第二行首
    .readlines()  # 读取每一行内容,存放于列表
    #### 如果文件过大会导致内存溢出
    # 方法一
    with open('a.txt',mode='rt',encoding='utf-8') as f:
        for line in f:
            print(line) # 同一时刻只读入一行内容到内存中
    
    # 方式二
    with open('1.mp4',mode='rb') as f:
        while True:
            data=f.read(1024) # 同一时刻只读入1024个Bytes到内存中
            if len(data) == 0:
                break
            print(data)
           
    # 写操作
    f.write('1111\n222\n')  # 针对文本模式的写,需要自己写换行符
    f.write('1111\n222\n'.encode('utf-8'))  # 针对b模式的写,需要自己写换行符
    f.writelines(['333\n','444\n'])  # 文件模式
    f.writelines([bytes('333\n',encoding='utf-8'),'444\n'.encode('utf-8')]) #b模式
    
  • 主动指定文件指针移动

    # 大前提: 文件内指针的移动都是以Bytes为单位,唯一例外的是t模式下的read(n),n 是以字符为单位
    with open('a.txt',mode='rt',encoding='utf8') as f:
        data = f.read(3) # 读取3个字符
    with open('a.txt',mode='rb') as f:
        data = f.read(3) # 读取3个Bytes
    # 之前文件内指针的移动都是由读/写操作而被动触发的,若想读取文件某一特定位置的数据,则则需要用f.seek方法主动控制文件内指针的移动,详细用法如下:
    # f.seek(指针移动的字节数,模式控制): 
    # 模式控制:
    # 0: 默认的模式,该模式代表指针移动的字节数是以文件开头为参照的
    # 1: 该模式代表指针移动的字节数是以当前所在的位置为参照的
    # 2: 该模式代表指针移动的字节数是以文件末尾的位置为参照的
    # 强调:其中0模式可以在t或者b模式使用,而1跟2模式只能在b模式下用
    
    # 0模式的使用
    with open('a.txt',mode='rt',encoding='utf-8') as f:
        f.seek(3,0)     # 参照文件开头移动了3个字节
        print(f.tell()) # 查看当前文件指针距离文件开头的位置,输出结果为3
        print(f.read()) # 从第3个字节的位置读到文件末尾,输出结果为:你好
        # 注意:由于在t模式下,会将读取的内容自动解码,所以必须保证读取的内容是一个完整中文数据,否则解码失败
    
    with open('a.txt',mode='rb') as f:
        f.seek(6,0)
        print(f.read().decode('utf-8')) #输出结果为: 好
        
    # 1模式的使用
    with open('a.txt',mode='rb') as f:
        f.seek(3,1) # 从当前位置往后移动3个字节,而此时的当前位置就是文件开头
        print(f.tell()) # 输出结果为:3
        f.seek(4,1)     # 从当前位置往后移动4个字节,而此时的当前位置为3
        print(f.tell()) # 输出结果为:7
        
    # a.txt用utf-8编码,内容如下(abc各占1个字节,中文“你好”各占3个字节)
    abc你好
    
    # 2模式的使用
    with open('a.txt',mode='rb') as f:
        f.seek(0,2)     # 参照文件末尾移动0个字节, 即直接跳到文件末尾
        print(f.tell()) # 输出结果为:9
        f.seek(-3,2)     # 参照文件末尾往前移动了3个字节
        print(f.read().decode('utf-8')) # 输出结果为:好
    
    # 小练习:实现动态查看最新一条日志的效果
    import time
    with open('access.log',mode='rb') as f:
        f.seek(0,2)
        while True:
            line=f.readline()
            if len(line) == 0:
                # 没有内容
                time.sleep(0.5)
            else:
                print(line.decode('utf-8'),end='')
    
上一篇:a链接中关于this的使用


下一篇:从新开始学Java JavaSE基础day09(继承的深度理解、super关键字、抽象类)