• Python学习笔记【第七篇】:文件及文件夹操作


     介绍

      我们用pytthon、C#、Java等这些编程语言,想要把文件(文字、视频....)永久保存下来就必须将文件写入到硬盘中,这就需要我们应用程序去操作硬件,我们这些编程语言是无法直接操作硬件的。就需要操作系统把复杂的硬件操作封装成接口给应用程序调用。这样用户应用程序就能对文件进行操作了。

    操作文件

      在Python中内置一个open对象是操作文件的方法。

    def open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True): 
    

      

     文件操作流程

    #1. 打开文件,得到文件句柄并赋值给一个变量
    #2. 通过句柄对文件进行操作
    #3. 关闭文件
    

      

    #1. 打开文件,得到文件句柄并赋值给一个变量
    f=open('a.txt','r',encoding='utf-8') #默认打开模式就为r
    
    #2. 通过句柄对文件进行操作
    data=f.read()
    
    #3. 关闭文件
    f.close()
    

     

    注意!!!  

    #第一点:
    打开一个文件包含两部分资源:操作系统级打开的文件+应用程序的变量。在操作完毕一个文件时,必须把与该文件的这两部分资源一个不落地回收,回收方法为:
    1、f.close() #回收操作系统级打开的文件
    2、del f #回收应用程序级的变量
     
    推荐傻瓜式操作方式:使用with关键字来帮我们管理上下文
    with open('a.txt','w') as f:
        pass
     
    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(...)是由操作系统打开文件,那么如果我们没有为open指定编码,操作系统会用自己的默认编码去打开文件,在windows下是gbk,在linux下是utf-8。
    文件以什么方式存的,就要以什么方式打开。
    
    f=open('a.txt','r',encoding='utf-8')

     打开文件的模式

    访问模式说明
    r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
    w 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
    a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
    rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
    wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
    ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
    r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
    w+ 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
    a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
    rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
    wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
    ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

    操作文件的方法

       f.read() # 读取所有内容,光标移动到文件末尾

       f.readline() # 读取一行的内容,光标移动到第二行首部

       f.readlines() # 读取每一行内容,返回列表

      data = '写入内容'

      f.write(data) # 写入文件,需要自己添加换行   

      f.write(data,encoding='utf-8')# 写入文件并且指定写入文件的编码格式

         f.writeline(['1','2','3']) # 文件以列表形式写入

       f.readable() # 文件是否可读

       f.writeable() # 文件是否可写

       f.closed #  文件是否关闭

       f.encoding # 如果文件打开模式为b ,则没有该属性  

       f.flush() # 立刻将文件内容从内存刷到硬盘上

       f.name # 文件名称

    文件内光标移动

      一: 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+等模式下测试效果

    文件的修改

      文件是存在硬盘上的,因而只存在覆盖,不存在修改如果想要修改文件就如下两种方式。

      方式一:将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,修改完毕后,再由内存覆盖到硬盘

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

    # -*- coding: utf-8 -*-
    
    # 声明字符编码
    # coding:utf-8
    import os
    
    # with open('../files/a.txt', 'r', encoding='utf-8') as a_f, open('../files/b.txt', 'w', encoding='utf-8') as b_f:
    #     a_data = a_f.read()
    #     a_data = a_data + "方式二:将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件"
    #     b_f.write(a_data)
    # os.remove('../files/a.txt')
    # os.rename('../files/b.txt', '../files/a.txt')
    
    
    with open('../files/a.txt', 'r', encoding='utf-8') as a_f, open('../files/b.txt', 'w', encoding='utf-8') as b_f:
        for line in a_f:
            b_f.write(line)
        b_f.write("方式二:将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件")
    os.remove('../files/a.txt')
    os.rename('../files/b.txt', '../files/a.txt')
    

      

    文件操作练习

    # -*- coding: utf-8 -*-
    
    # 声明字符编码
    # coding:utf-8
    # 文件全类容
    file_list = []
    
    
    # 定义文件生成器
    def file_generator():
        with open('../files/haproxy.conf', 'r', encoding='utf-8') as f:
            for row in f:
                yield row
    
    
    # 判断当前内容是否包含
    def is_contain(str):
        str = "backend %s" % str
        flag = False
        # 获取读取文件生成器
        generator = file_generator()
        for row in generator:
            r = row.strip()
            file_list.append(r)
            if r == str:
                flag = True
    
        print(file_list)
        return flag
    
    
    # 查询
    def fetch():
        # 是否查到标识
        flag = False
        print('=========欢迎进入查询功能=========')
        content = input('请输入您要查询的内容:')
        # 获取读取文件生成器
        generator = file_generator()
        backend_data = "backend %s" % content
        for row in generator:
            r = row.strip()
            # 查到了,如果开头为"backend"说明已经结束了。
            if flag is True and r.startswith('backend'):
                break
            if r == backend_data or flag is True:
                flag = True
                # 打印查询到的信息
                print(r)
        else:
            if flag is False:
                print('未查到当前节点下的内容。。。。')
    
    
    # 新增
    def insert():
        # 直接在文件中新加内容
        print('=========欢迎进入新增功能=========')
        content = input('请输入您要新增的内容:')
        if content is None:
            print("新增内容不能为空")
        # 思路也是先查询出原内容,组成列表,通过索引添加内容,在重写到原来的文件中
        pass
    
    
    # 修改
    def update():
        print('=========欢迎进入修改功能=========')
        # data = [{'backend': 'www.oldboy1.org', 'record': {'server': '2.2.2.4', 'weight': 20, 'maxconn': 3000}},{'backend': 'www.oldboy1.org', 'record': {'server': '3.3.3.3', 'weight': 30, 'maxconn': 1000}}]
        content = input('请输入您要查询的内容:').strip()
        # eval 转为列表结构
        data = eval(content)
    
        if is_contain(data[0]['backend']) is True:
            # 获取要修改的源数据
            old_server_record = '%sserver %s %s weight %s maxconn %s
    ' % (' ' * 8, data[0]['record']['server'],
                                                                           data[0]['record']['server'],
                                                                           data[0]['record']['weight'],
                                                                           data[0]['record']['maxconn'])
            # 要修改的数据
            new_server_record = '%sserver %s %s weight %s maxconn %s
    ' % (' ' * 8, data[1]['record']['server'],
                                                                           data[1]['record']['server'],
                                                                           data[1]['record']['weight'],
                                                                           data[1]['record']['maxconn'])
    
            old_server_record = old_server_record.strip()
            new_server_record = new_server_record.strip()
            print(old_server_record)
            print(new_server_record)
    
            print('修改前列表:')
            print(file_list)
            if old_server_record not in file_list:
                print('你要修改的记录不存在')
            else:
                index = file_list.index(old_server_record)
                file_list[index] = new_server_record
                print('修改后列表:')
                print(file_list)
                # 重新覆盖文件
                with open('../files/haproxy.conf', 'w+', encoding='utf-8') as f:
                    # 写入后就变成一行了???
                    f.writelines(file_list)
    
        else:
            print('对不起你要修改的内容不存在。。。')
    
    
    # 删除
    def delete():
        # 思路也是先查询出原内容,组成列表,通过索引删除内容,在重写到原来的文件中
        pass
    
    
    if __name__ == "__main__":
        msg = """
        1:查询
        2:新增
        3:修改
        4:删除
        5:退出
        """
        msg_dic = {
            '1': fetch,
            '2': insert,
            '3': update,
            '4': delete
        }
        while True:
            print(msg)
            # 接收用户输入并且去除空格
            choice = input("请输入功能选择:").strip()
            if choice == '5': break
            operation = msg_dic.get(choice)
            # print(operation) # 打印的是函数地址
            if operation is not None:
                # 调用函数
                operation()
            else:
                print("系统暂无此功能。。。")
    

      

     文件夹及路径操作方法

      对于文件夹的操作,首先我们要导入os模块

    import os
    
    =====OS模块====
    
    os.getcwd():获取当前路径
    os.listdir():展示当前目录内容 返回一个列表
    os.chdir():改变当前路径
    os.mkdir():创建目录
    os.rmdir():删除目录
    os.remove():删除文件
    os.rename():重命名
    
    os.path.isdir():判断是否是一个目录
    os.path.isfile():判断是否是一个文件
    os.path.join():路径拼接
    os.path.dirname():所在目录/父及目录
    os.path.abspath():绝对路径
    os.path.relpath():相对路径
    os.path.normpath():规范化路径
    os.path.getsize():资源大小
    os.path.getctime/getatime/getmtime:资源时间
    os.path.exists():路径是否存在
    os.path.isabs():是否是绝对路径
    
    
    '''
    

      

  • 相关阅读:
    整数的溢出或回绕
    C语言每日一题
    C语言刷“矩阵”类题目(2维矩阵/2级指针)
    C语言刷2数/3数/4数之和
    C语言刷数组题记录
    二、IAR创建工程并进行烧写
    三、STM8的学习笔记-----GPIO操作
    51单片机--------如何使用keil软件建立一个工程
    一、搭建mosquitto
    二、解决端口占用被占用情况
  • 原文地址:https://www.cnblogs.com/wendj/p/9237089.html
Copyright © 2020-2023  润新知