文件处理
Posted kwkk978113
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件处理相关的知识,希望对你有一定的参考价值。
# -*- 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‘)
以上是关于文件处理的主要内容,如果未能解决你的问题,请参考以下文章