zoukankan      html  css  js  c++  java
  • python基础学习-文件其他操作模式(补充)

    今日内容:

    1、文件模式

    x模式: x,只写模式(不可读;文件不存在则创建,文件存在则报错)

    with open('a.txt',mode='x',encoding='utf-8') as f:#如果a.txt文件已经创建,则报错
        pass
    with open('b.txt',mode='x',encoding='utf-8') as f:
        f.read()   #报错,x模式不可读
    with open('c.txt',mode='x',encoding='utf-8') as f:
        f.write('哈哈
    ')
    

    控制文件读写内容的模式
    t:(模式只能读文本文件)
    1.读写都是以字符串(unicode)为单位
    2.只能针对文本文件
    3.必须制定字符编码,即必须指定encoding参数
    b:binary模式(可以对任何数据进行操作,MP4,jpg,txt....)
    1.读写都是以bytes为单位
    2.可以针对所有文件
    3.一定不能指定字符编码

    错误演示:t模式只能读文本文件

    with open('爱情.mp4',mode='rt') as f:#这步只是打开文件,不会报错
        f.read()   #硬盘的二进制读入内存--t模式会将读入内存的内容进行decode解码,这个时候会出错
    
    
    with open('爱情.mp4',mode='rb') as f:  #binary二进制模式读写都是以bytes为单位,所以不用指定编码模式
        res=f.read()   #硬盘的二进制读入内存--b模式下,不做任何转换,直接读入内存
        print(res)  #bytes类型--当成二进制
    

    2、文件的操作的其他方法

    大文件拷贝案例,用循环方式读取
    扩展:###大文件的拷贝!!!
    方法一:

    #大文件的数据都是存储在内存里面,需要防止内存溢出
    #原文件的名字
    file_name="test.jpg"
    new_file_name,point,end_str=file_name.rpartition(".")
    print(new_file_name)
    print(point)
    print(end_str)
    
    dst_file_name=new_file_name+"[复件]"+point+end_str
    print(dst_file_name)
    
    dst_file=open(dst_file_name,"wb")
    file=open(file_name,"rb")
    
    #循环读取数据时采用循环读取(每次占用的空间只是新读取的数据,之前的数据会在内存中释放)
    while True:
        file_data = file.read(1024)#循环读取1024个字节的数据,可以指定读取数据的长度
        if len(file_data)>0:# if not file_data: #判断是否为空,不为空就写入目标文件里面
             print("读出的数据为:",file_data)
             dst_file.write(file_data)
        else:
            print("文件拷贝完毕!")
            break
    
    #注意:再进行大文件拷贝时,特别要注意写数据的地方,需要循环写入,防止一次性写入文件数据过大而导致内存溢出!!!
    
    dst_file.close()
    file.close()
    

    方法二:

    #循环读取文件
    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:
        while True:
            res = f1.read(1024)#循环读取1024个字节的数据,可以指定读取数据的长度
            if len(res)>0:# if not file_data: #判断是否为空,不为空就写入目标文件里面
                 print("读出的数据为:",res)
                 f2.write(res)
            else:
                print("文件拷贝完毕!")
                break
    

    应用:文件拷贝工具

    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)
    

    3、文件的高级操作:控制文件指针的移动

    3.1 读相关操作

       res=f.readline()   #一行一行读取数据
    while Ture:
        line=f.readline()
        if line(line)==0:
            break
        print(line)
    
       res=f.readlines()  # 把数据都一行行读取出来放入一个列表里输出
    

    #强调:这两种方式都是键数据一次性读入内存,如果数据内存过大容易造成内存溢出

    3.2 写相关操作

    f.writelines()  #相当于调了一个for循环
    
    with open('c.txt',mode='wt',encoding='utf-8') as f:
    l=['111
    ','2222','33333']
    for line in l:
        f.write(line)
    
    #以上可以用 f.writelines()实现
    
    f.writelines(l)
    
    #如果将写入模式变成  wb模式  就出错了,可以在列表里面指定编码模式处理,就可以用writelines
    
    with open('c.txt',mode='wb',encoding='utf-8') as f:
        l=[
            '111
    '.encode('utf-8'),
           '2222'.encode('utf-8'),
           '33333'.encode('utf-8')
           ]
        f.writelines(l)
    

    补充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)
    

    以下用法了解:

    with open('h.txt',mode='wb',encoding='utf-8') as f:
        f.write()  #将数据从内存写入硬盘上,将数据都攒够了再写入
        f.flush()  #每次都直接写入到硬盘,立马运过去
    
    f.readable()  # 文件是否可读
    f.writable()  # 文件是否可读
    f.closed  # 文件是否关闭
    f.encoding  # 如果文件打开模式为b,则没有该属性
    f.flush()  # 立刻将文件内容从内存刷到硬盘
    f.name
    

    3.3 控制指针的移动

    指针移动的单位都是以bytes/字节为单位
    只有一个情况特殊:
    t模式下的read(n),n代表的是字符个数
    with open('aaa.txt',mode='rt',encoding='utf-8') as f: #aaa文件存放 abc你好嘛
    res=f.read(4)

    print(res) #读出 abc你

    其他情况都是字节为单位
    f.seek(n,模式):n指的是移动的字节个数
    模式:
    0:参照物是文件开头位置
    f.seek(9,0)
    f.seek(3,0) #3
    1:参照物是当前指针所在的位置
    f.seek(9,1)
    f.seek(3,1) #12
    2:参照物是文件末尾位置,应该是倒着移动
    f.seek(-9,2) #3
    f.seek(-3,2) #9

    ##强调:!! 只有0模式可以在t下使用,1、2必须在b模式下用

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

    with open('aaa.txt',mode='rb',) as f:
       f.seek(9,0)
       f.seek(3,0)
       print(f.tell())  #3
       res=f.read()
       print(res.decode('utf-8'))  #你好
    
    with open('aaa.txt',mode='rb',) as f:
       f.seek(9,1)
       f.seek(3,1)
       print(f.tell())
       res=f.read()
       print(res.decode('utf-8'))
    
    with open('aaa.txt',mode='rb',) as f:
       f.seek(-9,2)
       f.seek(-3,2)
       print(f.tell())
       print(f.read().decode('utf-8'))  #好
    
    
    

    3.4 文件的修改方式有2种

    1、文件修改方式一

    文本编辑采用的就是这种方式

    实现思路:将文件内容发一次性全部读入内存,然后在内存中修改完毕后再覆盖写回原文件

    优点: 在文件修改过程中同一份数据只有一份

    缺点: 会过多地占用内存

    with open('a.txt',mode='rt',encoding='utf-8') as f:
        res=f.read()
        data=res.replace('alex','dsb')
        print(data)
    
    with open('a.txt',mode='wt',encoding='utf-8') as f1:
        f1.write(data)
    

    2、 文件修改方式二

    实现思路:以读的方式打开原文件,以写的方式打开一个临时文件,一行行读取原文件内容,修改完后写入临时文件...,删掉原文件,将临时文件重命名原文件名

    优点: 不会占用过多的内存

    缺点: 在文件修改过程中同一份数据存了两份

    with open('a.txt', mode='rt', encoding='utf-8') as f, 
            open('.a.txt.swap', mode='wt', encoding='utf-8') as f1:
        for line in f:
            f1.write(line.replace('alex', 'dsb'))
    
    os.remove('a.txt')
    os.rename('.a.txt.swap', 'a.txt')
    
    
    
    f = open('a.txt')
    res = f.read()
    print(res)
    
  • 相关阅读:
    Python学习之余,摸摸鱼
    Python 实现斐波那契数
    Linux下为什么目录的大小总是4096
    Python的精髓居然是方括号、花括号和圆括号!
    为什么说Python是最伟大的语言?看图就知道了!
    前端常用知识(会更新)
    Mysql 约束
    Navicat 安装
    Java后台将CTS格式转为标准日期时间格式返回给前端
    MySQL数据库报错“Zero date value prohibited”
  • 原文地址:https://www.cnblogs.com/dingbei/p/12504640.html
Copyright © 2011-2022 走看看