zoukankan      html  css  js  c++  java
  • Python基础(四)-文件操作

    一、文件操作的流程

    1)打开文件,得到文件句柄并赋值给一个变量

    2)通过句柄对文件进行操作

    3)关闭文件

    #方式一:
    #打开文件,得到文件句柄并赋值给一个变量
    f=open('a.txt','r',encoding='utf-8') #默认打开模式就为r
    
    #2通过句柄对文件进行操作
    data=f.read()
    
    #3关闭文件
    f.close()    #回收操作系统打开的文件
    #------------------------------------------------------
    #方式二:
    with open('a.txt','r') as read_f,open('b.txt','w') as write_f:
        data=read_f.read()
        write_f.write(data)

    注意:f=open(..)是由操作系统打开文件,由操作系统默认的编码决定(windows:gbk,linux:utf-8),若要保证不乱码,文件以什么方式存的,就要以什么方式打开

    二、文件打开的模式

    模式 描述
    r 只读模式,文件的指针在文件开头(默认模式,文件必须存在,不存在则抛出异常)
    rb 以二进制格式打开一个文件,指针默认在文件开头,一般用于图片或者视频等非文本
    r+ 读写模式,指针在文件开头
    w 只写,会先清空文件内容在进行写入(不可读,不存在则创建,存在则清空内容)
    wb 以二进制打开文件进行写入,会先清空文件内容在进行写入,一般用于图片等非文本
    w+写读,会清空文件内容在进行写入和读取
    a 追加写入,文件的指针在文件的结尾(不可读,不存在则创建,存在则只追加内容)
    ab 以二进制文件打开文件进行追加,文件指针会在结尾

    注意:

    1)以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码

    2)文件的相对路径与绝对路径

    • 绝对路径: 从磁盘根目录开始一直到文件名
    • 相对路径: 以当前目录为基准,在当前目录下相对路径就是当前文件名

    2.1、只读模式(r,rb)

    with open("read_file.txt",mode="r",encoding="utf-8") as f:
        print(f.read())
    
    #你好
    #abcdefghi
    

    encoding:字符集,根据文件的实际保存编码进行获取数据,常用的就是 utf-8,如果不指定encoding会出现乱码,因为open()会议操作系统的默认编码格式来获取数据(gbk),而文件实际保存的格式是utf-8

    with open("read_file.txt",mode="rb") as f:
        print(f.read())    
    
    #b'xe4xbdxa0xe5xa5xbd
    abcdefghi'
    

    rb 模式读取出来的数据是 bytes 类型,在 rb 模式下,不能选择 encoding 字符集

    rb 作用: 在读取非文本文件的时候,比如读取音频,图像,视频等信息可以用到

    文件读取的方式

    f.read()       #读取所有内容,光标移动到文件末尾 , 占用内存大,如果文件过大,容易导致内存崩溃
    f.readline()   #读取一行内容,每次读取出来的数据都会有一个
    ,可以使用.strip()或print(f.readline(),end=””)去除
    f.readlines()  #读取每一行内容,存放于列表中
    
    with open("read_file.txt",mode="r",encoding="utf-8") as f:
        print(f.readline())
        print(f.readline())
    
    #输出有空行
    你好
    
    abcdefghi
    -----------------------------------------------------------
    with open("read_file.txt",mode="r",encoding="utf-8") as f:
        print(f.readline().strip())
        print(f.readline().strip())
    
    #输出去除了空行
    你好
    abcdefghi
    ---------------------------------------------------------
    
    #循环读取,每次读取一行内容,不会产生内存溢出的问题
    with open("read_file.txt",mode="r",encoding="utf-8") as f:
        for line in f:
            print(line.strip())
    
    
    你好
    abcdefghi
    

    2.2、只写模式(w,wb)

    写模式如果文件不存在会自动创建文件,如果文件存在会情况原有内容,在写入新内容

    with open("read_file.txt",mode="w",encoding="utf-8") as f:
        f.write("只写模式")
        f.flush()
    
    #文件内容只剩下只写模式

    wb 模式下,可以不指定打开文件的编码,但是在写文件的时候必须将字符串转换成 utf-8 的bytes数据

    with open("read_file.txt",mode="wb") as f:
        f.write("wb模式".encode("utf-8"))
        f.flush()
    
    #文件内容:wb模式
    

    2.3、追加模式(a,ab)

    在追加模式下,写入的内容会追加在文件的结尾

    with open("read_file.txt",mode="a",encoding="utf-8") as f:
        f.write("abc")
        f.write("
    abc")   #使用
    换行
        f.flush()
    
    wb模式abc
    abc
    

    ab 模式的写法和 wb一样

    with open("read_file.txt",mode="ab") as f:
        f.write("ab模式".encode("utf-8"))
        f.flush()
    
    wb模式abc
    abcab模式
    

    2.4、读写模式(r+)

    对于读写模式,必须是先读. 因为默认的光标是在开头,当读完了之后在进行写入
    注意:在 r+ 模式下,如果读取了文件内容,无论读取内容多少,光标显示在是多少,再写入文件时都是在文件结尾写入

    with open("read_file.txt",mode="r+",encoding="utf-8") as f:
        print(f.read())
        f.write("
    r+模式")
        f.flush()
    
    #输出
    wb模式abc
    abcab模式
    
    #文件内容
    wb模式abc
    abcab模式
    r+模式
    

    2.5、写读模式(w+)

    先将文件所有的内容清空,然后写入,最后读取.但读取的内容为空

    with open("read_file.txt",mode="w+",encoding="utf-8") as f:
        f.write("w+模式")
        print(f.read())
        f.flush()
    
    #输出为空,因为写入之后光标在最后,后面没有内容读取
    #文件内容:w+模式
    

    2.6、追加读模式(a+)

    a+ 模式下,不论是先读还是后读,都是读取不到数据的,因为光标都在最后

    with open("read_file.txt", mode="a+", encoding="utf-8") as f:
        f.write("a+模式")
        print(f.read())
        f.flush()
    
    #没有输出,因为光标在文件结尾
    文件内容:w+模式a+模式
    

    三、文件其他操作

    3.1、光标移动seek()

    格式:seek(偏移量,偏移位置)

    seek(0)  ==>移动光标到开头

    seek(0,2)   ==>移动光标到结尾

    第一个参数:代表移动的偏移量

    第二个参数:从哪个位置进行偏移,默认是0

    • 0:表示开头
    • 1:表示当前位置
    • 2:表示结尾

    注意:seek(n) 光标移动到 n 位置,移动的单位是 byte,如果是 UTF-8 的中文部分要是3的倍速

    with open("read_file.txt",mode="r+",encoding="utf-8") as f:
        f.seek(0)        #移动光标到开头
        print(f.read())  #读取文件内容,此时光标在结尾
        f.seek(0)        #移动光标到开头
        f.seek(0,2)      #移动光标到结尾
        print(f.read())  #此时读取不到内容
        f.seek(0)        #移动光标到开头
        f.write("abc")   #覆盖开头的字符
        print(f.tell())  #查看光标位置
        f.flush()        #刷新文件到磁盘
    
    #文件内容:12345678  ==>  abc45678
    

    3.2、光标位置tell()

    with open("read_file.txt",mode="r+",encoding="utf-8") as f:
        print(f.tell())
        f.seek(3)   #光标移动3个字节
        print(f.tell())
        f.seek(0,2)  #光标移动到结尾
        print(f.tell())  

    3.3、文件截断truncate()

    截取文件是从开头开始,到你光标位置
    如果 truncate(n) 内 n 给出了位置,则就是从开头开始到 n 位置的截取

    with open("read_file.txt",mode="w+",encoding="utf-8") as f:
        f.write("abcdef")
        f.seek(3)
        f.truncate()  #截取开头到当前位置的内容
        f.seek(0)
        print(f.read())
    
    #abc

    四、文件操作方法总结

    f.read() #读取所有内容,光标移动到文件末尾
    f.readline() #读取一行内容,光标移动到第二行首部
    f.readlines() #读取每一行内容,存放于列表中
    
    f.write('1111
    222
    ') #针对文本模式的写,需要自己写换行符
    f.write('1111
    222
    '.encode('utf-8')) #针对b模式的写,需要自己写换行符
    f.writelines(['333
    ','444
    ']) #文件模式
    f.writelines([bytes('333
    ',encoding='utf-8'),'444
    '.encode('utf-8')]) #b模式
    
    
    f.readable() #文件是否可读
    f.writable() #文件是否可读
    f.closed #文件是否关闭
    f.encoding #如果文件打开模式为b,则没有该属性
    f.flush() #立刻将文件内容从内存刷到硬盘
    f.name
    

    注意

    1)read(3)

    • 文件打开方式为文本模式时,代表读取3个字符
    • 文件打开方式为b模式时,代表读取3个字节

    2)其余的文件内光标移动都是以字节为单位如seek,tell,truncate

    五、文件操作需求

    5.1、大文件读取最后一行(日志文件)

    #日志文件
    2016/12/25 a
    2016/12/26 b
    2016/12/27 c
    2016/12/28 a
    2016/12/29 d
    2016/12/30 s
    
    
    f=open('日志文件','rb')
    for i in f:
        offs=-10
        while True:
            f.seek(offs,2)
            data=f.readlines()  #readlines获取的是一个列表
            if len(data) > 1:   #列表的长度说明不只获取了最后一行
                print('文件的最后一行是%s' %(data[-1].decode('utf-8')))
                break
            offs*=2
    
    #文件的最后一行是2016/12/30 s

    5.2、文件的修改

    文件的数据是存放于硬盘上的,因而只存在覆盖、不存在修改这么一说,我们平时看到的修改文件,都是模拟出来的效果,具体的说有两种实现方式:

    方式一:将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,修改完毕后,再由内存覆盖到硬盘(word,vim,nodpad++等编辑器)

    import os
    with open("a.txt",mode="r",encoding="utf-8") as read_f,
            open(".a.txt.swap","w") as write_f:
        data = read_f.read()   #全部读入内存,如果文件很大,会很卡
        data = data.replace("aaa","bbb")  #在内存中修改
        write_f.write(data)   #一次性写入新文件
    
    os.remove("a.txt")
    os.rename(".a.txt.swap","a.txt")

    方式二:将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件

    import os
    with open("a.txt",mode="r",encoding="utf-8") as read_f,
            open(".a.txt.swap","w") as write_f:
        for line in read_f:
            line = line.replace("aaa","bbb")
            write_f.write(line)
    
    os.remove("a.txt")
    os.rename(".a.txt.swap","a.txt")
    
  • 相关阅读:
    JMeter学习使用(1)
    ip设置
    JMeter安装过程小问题
    appium-doctor
    使用 Xcode-Instrument-Automation -App -Ios自动化测试
    接口测试学习 -01
    在Windows下安装配置jforum测试环境
    root_one Android自动化测试02--git拉取及eclipse导入
    selenium+python学习总结-mac
    MySQL速学篇第四课
  • 原文地址:https://www.cnblogs.com/hujinzhong/p/11465800.html
Copyright © 2011-2022 走看看