zoukankan      html  css  js  c++  java
  • 文件处理

    # -*- coding: utf-8 -*-
    # @Time:
    # @Auther: kongweixin
    # @File:
    文件处理
    #######1.0文件与文件模式#############
    """
    1、什么是文件
    文件是操作系统提供给用户/应用程序操作硬盘的一种虚拟的概念/接口

    用户/应用程序
    操作系统(文件)
    计算机硬件(硬盘)

    2、为何要用文件

    用户/应用程序可以通过文件将数据永久保存的硬盘中
    即操作文件就是操作硬盘
    用户/应用程序直接操作的是文件,对文件进行的所有的操作,都是
    在向操作系统发送系统调用,然后再由操作将其转换为具体的硬盘操作


    3、如何用文件:open() :就是操作文件
    控制文件读写内容的模式
    强调:t和b不能让单独使用 必须跟r/a/w使用
    t文本(默认模式)
    1、读写都以str为单位的 (unicode(为单位在内存里))内存读写的文本文件()
    2、用于文本文件
    3、必须指定encoding='utf-8'
    b二进制/bytes
    控制文件读写操作的模式r只读模式w只写模式
    a只追加写模式
    +:r+,W+,a+


    4、基本操作流程
    打开文件
    读/写文件
    关闭文件
    5、资源回收与with语法


    6、详细介绍文件模式t,b,r,w.a.+

    """
    ##############2.0文件基础操作######################
    """
    扫盲
    #windows路径分隔符问题
    # 方法一,(window) 推荐
    # open ('C:a nbcd. txt') 会出现转义字符功能,故解决方法是在 "路径"前加r r"路径"
    open(r"C:a nbcd. txt") #r"字符串" rawstring(原生字符串)

    # 方法二(mac liunx )
    open ('C:/a/nb/c/d. txt')

    open ('a. txt') #(相对路径)当前文件夹为基准 同级目录下

    open ('G:2020老男孩全栈练习a.txt') #绝对路径 详细路径

    """
    # 这里a.txt自己创建最好 步骤:先点文件夹 鼠标右键--->new---->选择file 命名为a.txt
    f=open(r"a.txt",mode="rt",encoding="utf-8") #注意 "a.txt" 内不能存在空格
    # print(f) # f的值是一种变量

    #输出结果: <_io.TextIOWrapper name='a.txt' mode='rt' encoding='utf-8'>

    #2、操作文件:读/写文件,应用程序对文件的读写请求都是在向操作系统发送
    #系统调用,然后由操作系统控制硬盘把输入读入内存、或者与入硬盘

    # f=open(r"a.txt",mode="rt",encoding="utf-8")
    # c=f.read()
    # print(c)


    #3、关闭文件
    f.close()# 回收操作系统资源 但是变量还是存在的 但读不了


    # f=open(r"a.txt",mode="rt",encoding="utf-8")
    #
    # f.close()
    # print(f.read())

    # 再读取时会 ValueError: I/0 operation on closed file.
    # ValueError:对关闭的文件进行I / 0操作。

    # f=open(r"a.txt",mode="rt",encoding="utf-8")
    #
    # f.read()
    # del f #回收应用程序资源(pycharm不需要考虑)

    ###**注意**###
    # 1,只用open()时候, 写完以后需要用到f.close()进行关闭才能算结束]
    # 2,t模式下 存在 r w a 模式 读或写 mode="rt" 要用不同模式
    # 1.0 读模式 只能读

    # f=open(r"a.txt",mode="rt",encoding="utf-8")
    # print(f)
    # 输出结果: <_io.TextIOWrapper name='a.txt' mode='rt' encoding='utf-8'>
    # res=f.read()
    # print(res)
    # 输出结果: kongweixin is a good boy


    # 2.0 写模式 w 模式 只能写
    # f=open(r"a.txt",mode="wt",encoding="utf-8")
    # res=f.write("3.14159272653589793")
    # print(res)
    # print(f.read())

    #######3.0with上下管理#####
    #文件对象又称为文件
    # with文本 操作 可以省略了f.close()
    # with open("a.txt",mode="rt") as f1,
    # open("b.txt",mode="rt") as f2: #用于转义换行符
    #
    # res1 = f1.read()
    # res2 = f2.read()
    # print(res1)
    # print(res2)
    # 自动执行
    # f1.colse()
    # f2.colse()



    ######4.0指定字符编码######
    """
    强调:t和b不能单独使用,必须跟r/w/a连用
    t文本(默认的模式)
    1、读写都以str(unicode)为单位的
    2、文本文件(只能)
    3、必须指定encoding='utf-8

    """
    # ******重点*****
    #没有指定encoding参数操作系统会使用自己默认的编码
    #linux系统默认utf-8

    #windows系统默认gbk

    # with open ("c.txt",mode="rt",encoding="utf-8") as f: #需要加一个 encoding="utf-8" 进行命令操作系统
    # res=f.read()# t 模式会将f.read()读出的结果解码成unicode
    # print(res,type(res))

    # 内存 f 在硬件的变化 utf-8格式的二进制----解码---->unicode
    # 硬盘内容 (c.txt内容: utf-8 格式的二进制)


    #########5.0文件操作模式详解############


    # 以t模式为基础进行内存操作
    # 1、r(默认的操作模式):只读模式,当文件不存在时报错,当文件存在时文件指针跳到开始位置
    # with open('c.txt',mode='rt',encoding='utf-8')as f:
    # print("第一次读".center(50,"*"))
    # res=f.read() #把所有内容从硬盘读入内存
    # print(res)
    #
    # print("第二次读".center(50, "*"))
    # res1 = f.read() # 把所有内容从硬盘读入内存
    # print(res1)


    # 案例1
    #
    # inp_username =input (' your name>>: '). strip()
    # inp_password=input(' your password>>: '). strip()
    #
    # #验证
    # with open('user.txt',mode='rt',encoding='utf-8') as f:
    # for line in f:
    # # print(line)
    # username,password=line.strip(" ").split(":")
    # # print(l)
    # if inp_username == username and inp_password == password:
    # print('login successfull')
    # break
    # else:
    # print("账号或密码输入错误!!!")
    #
    # with open('user.txt',mode='rt',encoding='utf-8')as f:
    # res=f.read()
    # username,password=res.split(":")
    # if inp_username == username and inp_password == password:
    # print(' login successfull')
    # else:
    # print(' username or password error')


    # 应用程序====》文件
    # 应用程序====》数据库管理软件=》文件


    # 2.w只写模式(不要重要文件用w打开) .当文件不存在时 会创建空文件, 当文件存在时会清空文件
    # 指针位于开始位置

    # with open("d.txt",mode="wt",encoding="utf-8") as f:
    # # f.read() #报错 不可读
    # f.write("哈尽快哈U币 ")

    # with open("d.txt",mode="rt",encoding="utf-8") as f: #用rt不可写 wt不可读
    # f.write("123123132")

    # 强调1:
    # 在以w模式打开文件没有关闭的情况下,连续写入,新的内容总是跟在旧的之后
    # with open('d.txt',mode='wt',encoding='utf-8')as f:
    # f.write('擦勒1 ')
    # f.write('擦勒2 ')
    # f.write('擦勒3 ')

    # 强调2:
    # 如果重新以w模式打开文件,则会清空文件内容
    # with open('d.txt',mode='wt',encoding='utf-8')as f:
    # f.write('擦勒1 ')
    # with open('d.txt',mode='wt',encoding='utf-8')as f:
    # f.write('擦勒2 ')
    # with open('d.txt',mode='wt',encoding='utf-8')as f:
    # f.write('擦勒3 ')
    # w 模式不存在追加 只有在不关的情况下才不会被请清空 达到追加效果
    # 不然就会全部清空 从新写入

    # 案例:w模式用来创建全新的文件
    # 拷贝功能
    #
    # src_files=input('源文件路径>>:').strip()
    # dst_files=input('目标文件路径>>:').strip()
    # with open(r'{}'.format(src_files),mode='rt',encoding='utf-8')as f1,
    # open(r'{}'.format(dst_files),mode='wt',encoding='utf-8')as f2:
    # res=f1.read()
    # f2.write(res)


    # 3.a只追加写,在文件不存在时会创建空文档,在文件存在时文件指针会直接调到末尾
    # with open('e.txt',mode='at',encoding='utf-8')as f:
    # # f.read()# 报错 不能读
    # f.write("韩哈哈1 ")
    # f.write("韩哈哈2 ")
    # f.write("韩哈哈3 ")
    # f.write("韩哈哈4 ")

    # 强调 w 模式与 a 模式的异同:
    # 1 相同点:在打开的文件不关闭的情况下,连续的写入,新写的内容总会跟在前写的内容之后
    # 2 不同点:以 a 模式重新打开文件,不会清空原文件内容,会将文件指针直接移动到文件末尾,新写的内容永远写在最后


    # 案例:a模式用来在原有的文件内存的基础之上写入新的内容,比如记录日志、注册
    # 注册功能

    # name=input("your name---->")
    # password=input("your password---->")
    # 第一次
    # with open ("bd.txt",mode="wt",encoding="utf-8") as f:
    # f.write("{}:{} ".format(name,password))
    # 第二次
    # with open ("bd.txt",mode="at",encoding="utf-8") as f:
    # f.write("{}:{} ".format(name,password))


    # 了解 +模式 : +不能单独使用,必须配合r,w.a
    # 虽然是可读可写 但是以开头的模式r,w.a为基准

    # r+模式 文件不存在 会直接报错
    # w+模式 文件不存在 会直接创建
    # a+模式 文件不存在 会直接创建 指针在时跳到末尾

    # with open('g.txt', mode='r+', encoding=' utf-8') as f:
    # # print(f.read())
    # f.write("我草无情") # 跟在指针后边写
    # f.read() # 根本读不到 因为指针在后边
    #
    # with open('g. txt', mode='w+t ', encoding='utf-8') as f:
    # f.write('111 ')
    # f.write('222 ')
    # f.write('333 ')
    # print('====>', f.read())
    #
    # with open('g.txt', mode='a+t', encoding='utf-8') as f:
    # f.write('444 ')
    # f.write('555 ')
    # f.write('666 ')
    # print('====>', f.read())

    #######6.0 x模式(了解)###############

    # x模式(控制文件操作的模式)-》了解
    # x,只写模式[不可读;不存在则创建,存在则报错]

    # with open('a.txt',mode='x',encoding='utf-8')as f:
    # pass
    # with open('c.txt',mode='x',encoding='utf-8')as f:
    # f.read()
    # with open('d.txt',mode='x',encoding='utf-8')as f:
    # f.write('哈哈哈')


    #######7.0b 模式#################
    """
    控制文件读写内容的模式
    t模式
    1、读写都是以字符串(unicode)为单位
    2、只能针对文本文件
    3、必须指定字符编码 必须指定encoding 参数
    b模式
    1、读写都是以bytes为单位
    2、可以针对所有文件(图片 MP4 文本文件)
    3、一定不能指定字符编码 utf-8

    """
    # 错误演示:t模式只能读文本文件
    # with open(r'1.jpg',mode='rt')as f:
    # f.read()#硬盘的二进制读入内存-》t模式会将读入内存的内容进行decode解码操作

    # with open(r'1.jpg',mode='rb')as f:
    # res = f.read()
    # print(res) # bytes--->>当成二进制
    #硬盘的二进制读入内存-》b 模式下 直接读入内存 ,不做任何转换
    # b模式下:读就是直接把硬盘的东西直接放在内存里
    # 写就是把写在内存的东西直接放到硬盘

    # with open(r'd.txt',mode='rb') as f:
    # res=f.read()
    # print(res, type(res))
    #utf-8格式 一个字用三个bytes
    # 英文字符 直接显示英文符号

    # with open(r'd.txt',mode='rb')as f:
    # res=f.read()#utf-8的二进制
    # print(res,type(res))
    #
    # print(res.decode('utf-8'))

    # with open(r'd.txt',mode='rt',encoding="utf-8")as f:
    # res=f.read()#utf-8的二进制--->unicode---->>utf-8
    # print(res)

    # b模式 写入
    # with open(r'e.txt',mode='wb')as f:
    # res=f.write("你好hello".encode("utf-8")) # 写入时 要 确定编码格式防止乱码
    # print(res)


    # 文件拷贝工具
    # src_files=input('源文件路径>>:').strip()
    # dst_files=input('目标文件路径>>:').strip()
    # with open(r'{}'.format(src_files),mode='rb',encoding='utf-8')as f1,
    # open(r'{}'.format(dst_files),mode='wb',encoding='utf-8')as f2:
    # # res=f1.read() # 防止内存占用过大
    # # f2.write(res)
    # for line in f1:
    # f2.write(line)
    #

    #循环读取文件
    #方式一:自己控制每次读取的数据的数据量
    # with open(r' test. jpg ', mode=' rb') as f:# 自己找个照片是jpg的文件拉到文件夹里面

    # while True:
    # res=f.read(1024) #不会超出范围 故 while比较合适
    # if not res: #或者写为 if len(res)==0:
    #
    # break
    # print(len(res))


    # #方式二: 以行为单位读,当一行内容过长时会导致一次性读入内容的数据量过大
    # t模式
    # with open(r'g.txt',mode='rt',encoding='utf-8')as f:
    # for line in f:
    # print(line)
    # b模式
    # with open(r'g.txt',mode='rb')as f:
    # for line in f:
    # print(line)

    # with open(r'1.jpg',mode='rb')as f:
    # for line in f: #弊端是当一行十分长的时候 可能超出范围
    # print(line)
    #

    ########8.0 文件其他操作方法##############

    # *****重点*****
    # 读操作
    # f.read() # 读取所有内容,执行完该操作后,文件指针会移动到文件末尾
    # f.readline() # 读取一行内容,光标移动到第二行首部
    # f.readlines() # 读取每一行内容,存放于列表中

    # 强调:
    # f.read()与f.readlines()都是将内容一次性读入内容,如果内容过大会导致内存溢出,若还想将内容全读入内存,则必须分多次读入,有两种实现方式:
    # 方式一
    # with open('a.txt',mode='rt',encoding='utf-8') as f:
    # for line in f:
    # print(line) # 同一时刻只读入一行内容到内存中

    # 方式二
    # with open('1.mp4',mode='rb') as f:
    # while True:
    # data=f.read(1024) # 同一时刻只读入1024个Bytes到内存中
    # if len(data) == 0:
    # break
    # print(data)

    # 写操作
    # 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

    ###########9.0主动控制文件内指针移动################

    #大前提:文件内指针的移动都是Bytes为单位的,唯一例外的是t模式下的read(n),n以字符为单位

    # with open('a.txt',mode='rt',encoding='utf-8') as f:
    # data=f.read(3) # 读取3个字符
    #
    #
    # with open('a.txt',mode='rb') as f:
    # data=f.read(3) # 读取3个Bytes


    # 之前文件内指针的移动都是由读/写操作而被动触发的,若想读取文件某一特定位置的数据,则则需要用f.seek方法主动控制文件内指针的移动,详细用法如下:
    # f.seek(指针移动的字节数,模式控制):
    # 模式控制:
    # 0: 默认的模式,该模式代表指针移动的字节数是以文件开头为参照的
    # 1: 该模式代表指针移动的字节数是以当前所在的位置为参照的
    # 2: 该模式代表指针移动的字节数是以文件末尾的位置为参照的
    # 强调:其中0模式可以在t或者b模式使用,而1跟2模式只能在b模式下用




    ############### 详解 #############、

    # 一 , 0模式、

    # a.txt用utf-8编码,内容如下(abc各占1个字节,中文“你好”占6个字节(一个中文占三个字节))
    # abc你好 #共有9个人字节 1 1 1 3 3 (字节)
    # a b c 你 好
    # 0模式的使用
    # with open('a.txt',mode='rt',encoding='utf-8') as f:
    # f.seek(3,0) # 参照文件开头移动了3个字节
    # # print(f.tell()) # 查看当前文件指针距离文件开头的位置,输出结果为3
    # print(f.read()) # 从第3个字节的位置读到文件末尾,输出结果为:你好
    # # 注意:由于在t模式下,会将读取的内容自动解码,所以必须保证读取的内容是一个完整中文数据,否则解码失败

    # with open('a.txt',mode='rb') as f:
    # f.seek(6,0)
    # print(f.read().decode("utf-8")) #输出结果为: 好

    #而且这里要注意字符编码******** (在设置a.txt 文件时右下有utf-8 ) window的是gbk liunx 的是utf-8




    # 1模式详解
    # 1模式的使用

    # with open('a.txt',mode='rb') as f:
    # f.seek(3,1) # 从当前位置往后移动3个字节,而此时的当前位置就是文件开头
    # print(f.tell()) # 输出结果为:3
    # f.seek(4,1) # 从当前位置往后移动4个字节,而此时的当前位置为3
    # print(f.tell()) # 输出结果为:7

    # abc你好 #共有9个人字节 (文件开头) 0 1 1 |1 3 3 (字节)
    # 0 a b | c| 你 好
    # |向后移动一位 这位是则是c c 是字母 所以 输出结果是前几个字母字节的总和 ,故 是3
    # 结果": 7 同样的道理 这里就略过 !!!




    # 2模式 详解
    # a.txt用utf-8编码,内容如下(abc各占1个字节,中文“你好”各占3个字节)
    # abc你好

    # 2模式的使用
    # with open('a.txt',mode='rb') as f:
    # f.seek(0,2) # 参照文件末尾移动0个字节, 即直接跳到文件末尾 那就是1+1+1+3+3 a b c 你 好
    # print(f.tell()) # 输出结果为:9
    # f.seek(-3,2) # 参照文件末尾往前移动了3个字节
    # print(f.read().decode('utf-8')) # 输出结果为:好

    # abc你好 #共有9个人字节 (文件开头) 0 1 1 |1 3 3 (字节)
    # 0 a b | c| 你 好

    # 看完这里大家可以理解 0 1 2 模式 说白了就是f.seek(参数1,参数2) 中的参数2

    # 建议自己找个文件 log , jpg 都可以 (前提是b 模式下, t模式只用于文本文件 )





    # ########10.0文件修改##########
    """
    # 文件a.txt内容如下(建议为字符编码为utf-8)
    张一蛋 山东 179 49 12344234523
    李二蛋 河北 163 57 13913453521
    王全蛋 山西 153 62 18651433422

    #如果不知道怎么改字符编码就直接写进去 效果一样
    with open (r"b.txt",mode="wt",encoding="utf-8") as f:
    f.write("张一蛋 山东 179 49 12344234523 "
    "李二蛋 河北 163 57 13913453521 "
    "王全蛋 山西 153 62 18651433422 ")
    # 执行操作
    with open('a.txt',mode='r+t',encoding='utf-8') as f:
    f.seek(9)
    f.write('<妇女主任>')

    # 文件修改后的内容如下
    张一蛋<妇女主任> 179 49 12344234523
    李二蛋 河北 163 57 13913453521
    王全蛋 山西 153 62 18651433422

    # 强调:
    # 1、硬盘空间是无法修改的,硬盘中数据的更新都是用新内容覆盖旧内容
    # 2、内存中的数据是可以修改的

    """


    """
    文件对应的是硬盘空间,硬盘不能修改对应着文件本质也不能修改,
    那我们看到文件的内容可以修改,是如何实现的呢?
    大致的思路是将硬盘中文件内容读入内存,然后在内存中修改完毕后再覆盖回硬盘 具体的实现方式分为两种:

    """

    # 文件修改方式一 :文本编辑器修改方式:
    # 实现思路:将文件内容发一次性全部读入内存,然后在内存中修改完毕后再覆盖写回原文件
    # 优点: 在文件修改过程中同一份数据只有一份
    # 缺点: 会过多地占用内存
    """
    db.txt内容如下:
    kwx:123
    SB:456
    # 文件修改后的内容如下
    kwx:123
    SB:456


    """
    """
    因为知道w 是会清空从新写的(但是 它是在内存里面的的) 所以 data还是存在的
    只需要从新写就可以覆盖硬盘里的源文件内容
    (注意 :硬盘里只存在覆盖 不存在修改)!
    !原理就是:将硬盘里面的东西放进内存里打开,内存是可以进行修改的
    点击保存时,才进行对硬盘源文件的覆盖从而得到保存作用!!

    """
    # with open('db.txt',mode='rt',encoding='utf-8') as f:
    # data=f.read()
    # print(data)
    # with open('db.txt',mode='wt',encoding='utf-8') as f:
    # f.write(data.replace('lili','SB'))# replace()字符串类型里面的(替换)
    #



    # **文件修改方式二 :修改逻辑不变,只不过是分批进行写入
    # 实现思路:以读的方式打开原文件,以写的方式打开一个临时文件,一行行读取原文件内容,修改完后写入临时文件...,删掉原文件,将临时文件重命名原文件名
    # 优点: 不会占用过多的内存
    # 缺点: 在文件修改过程中同一份数据存了两份
    """
    原理讲解:首先使我们的源文件 db.txt 和新文件 .db.txt.swap 从源文件中进行单行读取
    然后新文件里面进行写文件 等全部写完之后.
    os.remove('db.txt') 将源文件进行删除 (remove 是删除的 #如果不知道,那内置函数方法没有掌握好)
    os.rename('.db.txt.swap','db.txt') (进行从命名新文件)
    """

    # import os#这里是模块调用
    #
    # with open('db.txt',mode='rt',encoding='utf-8') as read_f,
    # open('.db.txt.swap',mode='wt',encoding='utf-8') as wrife_f:#.db.txt.swap (liunx) 一种隐藏文件
    # for line in read_f:
    # wrife_f.write(line.replace('SB','kevin'))
    #
    # os.remove('db.txt')
    # os.rename('.db.txt.swap','db.txt')

  • 相关阅读:
    钉钉outgoing机器人小项目开发
    js根据cookie判断,一天之内只弹出一次弹窗
    js倒计时功能
    jquery的$().each,$.each的区别
    VS代码提示自动高亮
    winform当前屏幕大小
    动态增删改控件
    datagridveiw样式
    sql 语句 提取中文的首字母
    按键监听及重写
  • 原文地址:https://www.cnblogs.com/kwkk978113/p/13231358.html
Copyright © 2011-2022 走看看