zoukankan      html  css  js  c++  java
  • Python文件修改和常用方法

      为了更好地说明接下来的文件修改操作,我们有必要先来学习下文件操作的常用方法。

    一、文件处理中的常用方法 

    #!/usr/bin/env python3
    #-*- coding:utf-8 -*-
    # write by congcong
    
    # flush() 把文件从内存强制刷新到硬盘
    f = open('w_flush.txt',mode='r+')
    f.write("这是强制刷新到硬盘的文件!")
    f.flush()
    print("查看文件:",f.read())
    # f.close()
    
    
    # readable() 判断是否可读
    print(f.readable())  #输出:True
    f1 = open("w_flush.txt",mode='w') #文件的写操作
    f1.write('判断文件是否可读!')
    f1.flush()
    print(f1.readable()) # 输出:False (表明写操作时文件也是不可读的)
    
    
    #  readline() 输出一行,碰到
     或者 
    结束
    f = open('w_flush.txt',mode='a',encoding='gbk')
    f.write('我是第一行!')
    f.write('
    我是第二行!')
    f = open('w_flush.txt',mode='r',encoding='gbk')
    print(f.readline())#输出:我是第一行!
    
    # tell() 返回光标当前位置,以字节为计算单位
    print(f.tell()) #输出 ; 14,因为编码为 gbk ,gbk每个中文字符占两个字节,所以此时光标位于第一行末尾
    
    # seek() 将光标移到指定字节位置,以字节为计数单位
    print(f.seek(2)) #输出:2
    print(f.readline()) # 输出;是第一行!
    print(f.seek(4))  #输出:4
    print(f.readline()) #输出:第一行
    
    # seekable() 判断文件能否seek,linux中使用(一切皆文件)
    
    # read() 括号内指定长度时,就从当前位置开始读几个字符;括号内没有指定长度时,就读全部文件,以字符为单位
    print(f.tell())
    print(f.seek(0))
    print(f.read(2)) #输出:我是
    
    # truncate() 按指定长度截断文件,括号内指定长度时,就从文件开头开始截断指定长度;不指定长度时,从当前位置到尾部的内容全部去掉
    #此方法必须是在写模式下使用
    f = open('w_flush.txt','r+',encoding='gbk')
    print(f.seek(4)) #输出;4
    print(f.tell())  # 输出;4
    print(f.truncate(8)) #输出;8
    print(f.seek(0)) #输出 :0
    
    f.close()

      了解了以上的方法,我们就能愉快地进行文件修改操作了。

    二、文件修改操作

      当我们以读写(r+)模式打开文件时,,默认会把新增的内容追加到文件最末尾。

      这是为什么呢?那我们如果想要修改中间的内容该怎么办呢?

      还记得我们刚学过一个tell()方法吗,它的单位是字节,当我们读一段内容的时候,光标会跟着移动,文件读完了,光标就会移到末尾,

    再接着写,光标自然会跟着移动,写完后,光标就停留在末尾了,我们可以用tell()方法验证一下猜想,打印此时光标位置,

    此时,我们再想读文件内容,就没有任何输出了,都是空白的。这就解释了为何我追加的内容为何无法读出来。

      至于为何追加内容会从末尾开始,就容易理解了,当你以追加模式打开文件时,光标会默认移到文件尾部,再开始写。

      而文件修改就要用到另一个方法了,seek()方法,它的作用就是移动光标到指定位置,移动的单位是字节,当我们想修改某个地方,

    使用seek()方法将光标移到指定位置就可以再修改了,下面我们可以试一下:

    # write.txt的原本内容是 :这是第一个我用Python写的文件!
    # 现在我要将‘写’改为‘修改后’
    
    f = open(file='write.txt',mode='r+',encoding='gbk')
    print('修改前:
    ',f.read(),f.tell()) # 读出修改前的文件内容,并打印当前光标位置
    f.seek(20)          # 将光标移到第20个字节后的位置(GBK编码一个汉字占2字节,英文占1字节)
    f.write('修改后')     # 写入修改内容
    f.seek(0)           # 将光标移到文件开头
    print(f.tell())     # 打印当前光标位置
    print('修改后:
    ',f.read(),f.tell()) # 读出修改后的文件内容,并打印当前光标位置
    
    f.close() # 关闭文件
    
    '''
     这是第一个我用Python写的文件! 29
    0
    修改后:
     这是第一个我用Python修改后件! 29
    '''

      没有报错,正常执行,‘写’ 也的确被改成了 ‘修改后’ ,文件大小也并未改变,但是也有我们不想修改的内容被覆盖了,这就尴尬了。。。

      原因在这里

        这是硬盘的存储原理导致的,当你把文件存到硬盘上,就在硬盘上划了一块空间,存数据,等你下次打开这个文件 ,seek到一个位置,每改一个字,就是把原来的覆盖掉,如果要插入,是不可能的,因为后面的数据在硬盘上不会整体向后移。所以就出现 当前这个情况 ,你想插入,却变成了会把旧内容覆盖掉。

      解决方法呢?

        想修改当然可以,但是不要在硬盘上修改,把内容全部读到内存里,数据在内存里可以随便增删改查,修改之后,把内容再全部写回硬盘,把原来的数据全部覆盖掉。

        例如: 

    # -*- coding:utf-8 -*-
    
    import os       # 导入模块
    
    f1 = 'notebook.txt'    # 待修改的文件
    f2 = 'note_new.txt'    # 修改后的文件
    f_old = open(f1,mode='r',encoding='utf-8')   # 打开待修改的文件
    f_new = open(f2,mode='w',encoding='utf-8')    # 写入修改的文件    
    
    old_str = ''       # 待修改的字符串
    new_str = 'one'    # 修改后的字符串
    count = 0           # 统计修改次数
    for line in f_old:   # 循环读
        if old_str in line:
            newline = line.replace('','one')    # 替换
            count += 1    #  每修改一次自增1
        else:
            newline = line
        f_new.write(newline)     # 写入修改后的文件
    f_old.close()     # 依次关闭
    f_new.close()
    os.replace('note_new.txt','notebook.txt')    # 用新文件里的内容替换旧文件 
    print('修改次数:'count)     # 修改次数:5
  • 相关阅读:
    浅谈VUE中的深拷贝与浅拷贝Object.assign()方法
    echarts详细
    实现HTML调用打开本地软件文件
    el-select 中放置el-tree
    关于前端平时需要用到的方法(未完成)
    10个Vue开发技巧助力成为更好的工程师
    element ui 弹出组件的遮罩层以及多层遮罩解决办法。。
    vue样式穿透 v-deep与deep的具体使用
    # Ansible安装指南
    Linux笔记—网络管理
  • 原文地址:https://www.cnblogs.com/schut/p/8410961.html
Copyright © 2011-2022 走看看