• 【Python基础】文件操作


    文件操作

    计算机系统分为:计算机硬件,操作系统,应用程序三部分。

      我们用Python或其他语言编写的应用程序若想要把数据永久保存下来,必须要保存于硬盘中,这就涉及到应用程序要操作

    硬件,众所周知,应用程序是无法直接操作硬件的,这就用到了操作系统。操作系统把复杂的硬件操作封装成简单的接口给用

    户/应用程序使用,其中文件就是操作系统提供给应用程序来操作硬盘虚拟概念,用户或应用程序通过操作文件,可以将自己的

    数据永久保存下来。有了文件的概念,我们无需再去考虑操作硬盘的细节,只需要关注操作文件的流程:

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

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

    #3. 关闭文件

    文件 读 r 操作

    f=open('陈粒',encoding='utf-8')
    data=f.read()
    print(data)
    f.close()
    
    f=open('xxx')
    data=f.read()
    print(data)
    
    
    f=open('陈粒','r',encoding='utf-8')
    data=f.read()
    # print(data)
    print(f.readable())
    print('第1行',f.readline(),end='')
    print('第2行',f.readline())
    print('第3行',f.readline())
    # for i in range(1):
    #     pass
    print('第4行',f.readline())
    print('第5行',f.readline())
    print('第6行',f.readline())
    print('第7行',f.readline())
    
    data=f.readlines()
    print(data)
    f.close()
    读文件

    文件 写 w 操作

    f=open('陈粒1','w',encoding='utf8')
    # f.read()
    f.write('11111111
    ')
    f.write('222222222
    ')
    f.write('333
    4444
    555
    ')
    # f.writable()
    f.writelines(['555
    ','6666
    '])
    f.writelines(['555
    ','6666
    ',1]) # 文件内容只能是字符串,只能写字符串
    f.close()
    写文件

    文件 追加 a 操作

    f=open('陈粒1','a',encoding='utf-8')
    f.write('追加方式写到文件最后')
    追加写操作

    "+" 表示可以同时读写某个文件

    r+, 读写【可读,可写】

    w+,写读【可读,可写】

    a+, 写读【可读,可写】

    文件修改

    src_f=open('xxx','r',encoding='gbk')
    data=src_f.readlines()
    src_f.close()
    
    # for i in data:
    #     print(i)
    print(data)
    dst_f=open('xxx','w',encoding='gbk')
    # dst_f.writelines(data)
    dst_f.write(data[0])
    dst_f.close()
    
    with open('a.txt','w') as f:
        f.write('1111
    ')
    
    
    src_f=open('xxx','r',encoding='gbk')
    dst_f=open('xxx','w',encoding='gbk')
    修改文件

    推荐-以 with 方式打开多个文件

    with open('xxx','r',encoding='gbk') as src_f,
            open('xxx_new','w',encoding='gbk') as dst_f:
        data=src_f.read()
        dst_f.write(data)
    
    f=open('a.txt')
    print(f.encoding) #查看文件编码
    View Code
    with open('a.txt','r',encoding='utf8') as fa:
        for row in fa:      #fa获得多行数据组成的列表
        print(row.strip())

    以 bytes(二进制)方式打开文件(主要是视频、音频文件)

    f=open('test11.py','rb',encoding='utf-8')     #b的方式不能指定编码
    f=open('test11.py','rb') #b的方式不能指定编码
    data=f.read()
    
    #'字符串'---------encode---------》bytes
    #bytes---------decode---------》'字符串'
    
    print(data)
    print(data.decode('utf-8'))
    f.close()
    
    
    f=open('test22.py','wb') #b的方式不能指定编码
    f.write(bytes('1111
    ',encoding='utf-8'))
    f.write('中国'.encode('utf-8'))
    
    f=open('test22.py','ab') #b的方式不能指定编码
    f.write('中国'.encode('utf-8'))
    
    open('a.ltxt','wt')
    View Code

    补充:需求:读取几万行日志文件的最后一行
    f.readlines() 直接全部读出来放在内存中 很耗内存空间

    # f=open('日志文件','rb')
    # data=f.readlines()
    # print(data[-1].decode('utf-8'))
    
    f=open('日志文件','rb')
    
    # for i in f.readlines():
    #     print(i)
    
    #循环文件的推荐方式,以行为单位读取,取一行用一行 不全部放在内存中
    # for i in f:
    #     print(i)
    
    for i in f:
        offs=-10
        while True:
            f.seek(offs,2)
            data=f.readlines()
            if len(data) > 1:
                print('文件的最后一行是%s' %(data[-1].decode('utf-8')))
                break
            offs*=2
    View Code

     ###操作文件的一些方法总结

    #掌握
    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

    """
    练习,利用b模式,编写一个cp工具,要求如下:
      1. 既可以拷贝文本又可以拷贝视频,图片等文件
      2. 用户一旦参数错误,打印命令的正确使用方法,如usage: cp source_file target_file
      提示:可以用import sys,然后用sys.argv获取脚本后面跟的参数
    使用cmd命令行执行test1.py 后面可以跟上参数,用sys.argv获取参数列表[test1.py,arg1,arg2...]
    """

    import sys
    if len(sys.argv) != 3:
        print('usage: cp source_file target_file')
        sys.exit()
    
    print(sys.argv)     #['test1.py', 'aa.txt', 'bb']
    source_file,target_file=sys.argv[1],sys.argv[2]
    with open(source_file,'rb') as read_f,open(target_file,'wb') as write_f:
        for line in read_f:
            write_f.write(line)

    文件内光标移动

    一: read(3):

      1. 文件打开方式为文本模式时,代表读取3个字符

      2. 文件打开方式为b模式时,代表读取3个字节

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

    注意:

      1. seek有三种移动方式0,1,2,其中1和2必须在b模式下进行,但无论哪种模式,都是以bytes为单位移动的

      2. truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果

    文件的修改

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

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

    import os
    
    with open('./a.txt','r') as read_f,open('./newa.txt','w') as write_f:
        data=read_f.read() #全部读入内存,如果文件很大,会很卡
        data=data.replace('alex','SB') #在内存中完成修改
    
        write_f.write(data) #一次性写入新文件
    
    os.remove('./a.txt')
    os.rename('./newa.txt','a.txt')

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

    import os
    
    with open('./a.txt') as read_f,open('./newa.txt','w') as write_f:
        for line in read_f:
            line=line.replace('alex','SB')
            write_f.write(line)
    
    os.remove('./a.txt')
    os.rename('./a.txt','./a.txt') 

    案例:在文件中查询内容

    """实现在文件中 查询某一行打印出这行下级的内容"""
    def fetch(data):
        backend_data = "backend %s"%data
        with open('haproxy.conf','r') as read_f:
            tag = False
            res = []
            for read_line in read_f:
                if read_line.strip() == backend_data:
                    tag = True
                    continue
                if tag and read_line.startswith("backend"):
                    break
                if tag and read_line.strip() is not None:
                    print(read_line.strip())
                    res.append(read_line.strip())
        return res
    
    def add():
        pass
    
    def change():
        pass
    
    def delete():
        pass
    
    if __name__ == '__main__':
        msg = '''
            1:查询
            2:添加
            3:修改
            4:删除
            5:退出
        '''
        msg_dic = {
            '1': fetch,
            '2': add,
            '3': change,
            '4': delete,
        }
        while True:
            print(msg)
            choice = input("输入你的选项>>>").strip()
            if not choice:continue
            if choice =="5":break
            data = input("输入你的数据>>>").strip()
            res = msg_dic[choice](data) #res 是所选择函数的返回值
            print(res)

    补充知识:多层while循环嵌套时 如何跳出?

    """输入一个quit_all 退出所有while层的循环"""
    tag=True
    while tag:
        print('leve1')
        choice=input("level1>>: ").strip()
        if choice == 'quit':break
        if choice == 'quit_all': tag = False
        while tag:
            print('level2')
            choice = input("level2>>: ").strip()
            if choice == 'quit': break
            if choice == 'quit_all': tag = False
            while tag:
                print('level3')
                choice = input("level3>: ").strip()
                if choice == 'quit': break
                if choice == 'quit_all': tag = False

    文件/文件夹操作参考 os模块

    # import os
    # # os.rename('a.txt','a.txt.bak')
    # os.rename('b.txt','aa.py')     #rename 修改文件或文件夹名称(或类型)

    参考:http://www.cnblogs.com/linhaifeng/articles/5984922.html#_label28

  • 相关阅读:
    追加上传
    反面教材 构造构造 json 数据
    Reading table information for completion of table and column names
    (原创)c#学习笔记04--流程控制03--分支03--switch语句
    (原创)c#学习笔记04--流程控制03--分支02--if语句
    (原创)c#学习笔记04--流程控制03--分支01--三元运算符
    (原创)c#学习笔记04--流程控制02--goto语句
    (原创)c#学习笔记04--流程控制01--布尔逻辑02--按位运算符
    (原创)c#学习笔记04--流程控制01--布尔逻辑01--布尔赋值运算符
    (原创)c#学习笔记03--变量和表达式04--表达式04--命名空间
  • 原文地址:https://www.cnblogs.com/XJT2018/p/10854939.html
Copyright © 2020-2023  润新知