01 文件处理
Posted yang1333
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了01 文件处理相关的知识,希望对你有一定的参考价值。
01 文件处理
- 主要围着open()功能的使用
一、引入
1、什么是文件
- 文件是操作系统提供给 用户或者是应用程序 用于操作硬盘的虚拟 概念或者说接口。
2、为什么要有文件?
- 用户或者应用程序可以通过文件,将数据永久保存到硬盘中。
- 详细的说:用户和应用程序操作的是文件,对文件的所有操作,都是向操作系统发送系统调用,然后再由操作系统将其转换成具体的硬盘的操作。
二、文件操作的基本流程
1、基本流程
"""
伪代码示例:
f = open(r'指定你要打开文件的文件路径', mode='rt,)
r:
raw_str,指的是原生得字符串,里面得反斜杠,都会被视为普通字符。
windows中路径分隔符解决方案:
方案一(推荐):在文件路径前加r
方案二:windows中会把左斜杠/,默认转换成右斜杠。使用 'C:/a.txt/nb/c/d.txt',默认会转成 'C:a.txt
bcd.txt'。
绝对路径与相对路径:
相对路径:会以你当前执行文件所在的文件夹下为基准去找。
优点:简洁
缺点:当你执行文件移动,被操作文件将找不到。
绝对路径:从盘符的根目录下开始直接定位到你需要操作的文件地址。
优点:执行文件移动到任意目录中都可以找到所需要操作的文件地址。
缺点:臃肿
rt:
默认控制文件读写操作的模式是r,只读模式。
默认控制文件读写内容的模式是t,t文本模式。
原理解析:
f = open 占用了2部分的内存空间:
第一部分:open占用的是操作系统的的内存空间。由操作系统的映射到了应用程序的内存空间中。
第二部分:我们知道f的值是一种变量,而变量都是归属于python的内存空间,也就是说。f占用的就是应用程序的内存空间。
"""
# 1、打开文件
f = open(r'aaa/a.txt', mode='rt') # open是向操作系统发起系统调用。
# 2、操作文件:读写/文件
res = f.read() # f.read()向操作系统发送请求,让操作系统把文件从硬盘读入内存。
print(res)
# 3、关闭文件
f.close() # 告诉操作系统,回收刚刚读入文件内存占用的内存空间。(需要考虑的操作:操作系统打开文件,如果没有及时关闭,就会无意义的占用操作系统的内存空间,并且还会无意义的占用操作系统的操作文件数。如果没有指定关闭,操作系统不会立即清除该内存空间的占用,只有过了一定的时间,操作系统才会把没有意义的占用清除,而这种清除时间间隔对于我们来说感觉不到,但是对于计算机来说,是非常大的损耗。补充:操作系统打开文件的文件是有限的,如果开打文件过多,就会影响你的电脑性能。)
f.read() # 注意:f.close()之后,不能在对文件进行操作了。这个时候操作系统已经把调用的文件关闭回收了,如果继续调用就会报错(ValueError: I/O operation on closed file.)。
del f # 注意:del f 的顺序要放在f.close()后面。(不需要考虑的操作:有python的GC机制管理)
2、资源回收与with上下文管理
"""
引入:
with称之为:上下文管理,上文帮你打开文件,下文帮你关闭文件。
注意:a并不是(10.57)
强调:
open对应的赋值对象f,称之为文件对象、又有人称之为‘文件句柄’(柄:游戏手柄干嘛的?就是用来操作游戏的。那么我也也可以推理出,其实‘文件句柄’,就是用来远程控制文件的。)
"""
# 1、with打开单个文件
with open('a.txt', mode='rt') as f:
res = f.read()
print(res)
# 上面没有指定f.close(), with会等其子代码块群不运行完毕以后,会帮你自动调用f.close()。
# 2、with同时打开多个文件
# with open('a.txt', mode='rt') as f1, open('b.txt', mode='rt') as f2: # 当你的一行代码过长,可以使用右斜杠(注意:右斜杠并不是换行,而是转义且分隔。)
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)
3、指定操作文本文件的字符编码
- 上面没有指定操作文本的字符编码,接下来我们需要指定??:
# 强调:如果你操作的是文本文件,那么就使用t模式。(仅限于文本文件)
# 1、r模式下的读操作
with open('c.txt', mode='rt') as f:
res = f.read() # f.read()发生了什么过程?向操作系统发送请求,告诉操作系统,我要把c.txt的内容由硬盘往内存读。而我们需要注意的是这个时候硬盘里面躺的是一堆二进制,我们需要使用一种对应的编码格式把二进制由硬盘读入内存,并由unicode转换成相应的字符。
# open发生的2步骤:1、定义1个变量,2、向操作系统发生请求,让操作系统帮我打开文件。{open第二个步骤中:如果没有指定编码,操作系统就会默认使用自己默认的编码打开文件,如果你的文本文件是用utf-8编码存入硬盘,那么如果你的操作系统是windows,它会使用默认的编码GBK去对应读取硬盘中的二进制文件,如果你之前文件中含有中文字符那么这个时候,GBk的编码表按照它二进制与表的对应关系读出(读出中文2个Bytes),但是我们要知道的是,存入的时候utf-8按照它的二进制与表的对应关系存入(存入中文3个Bytes),在这个时候就会报出解码错(Unicode解码错误:'gbk'编解码器无法解码16位的字节)}
# 展示硬件当前状态??:
# 内存:utf-8格式的二进制 --> 解码 --> unicode(t模式会将f.read()读出的utf-8结果,解码成unicode)
# 硬盘(c.txt内容:utf-8格式的二进制)
# 展示过程??:
# 存入:内存中查看到c.txt内容 --> 相应字符按照unicode与utf-8编码对应表转成二进制 --> 把utf-8格式的二进制存入硬盘(c.txt内容)
# 读出:硬盘(c.txt内容:utf-8格式的二进制) --> 把二进制按照utf-8编码格式对照表读入内存 --> 按照unicode与utf-8编码对应表转成相应字符 --> 打印内存中查看到c.txt内容
print(res, type(res))
# 2、-------w模式的写操作 ------------(没整理)
with open('c.txt', mode='rt') as f:
f.write()
print(res, type(res))
# 单独讨论
# 把字符写入硬盘encode
# 读出decode
'哈哈哈'。
三、文件的操作模式
??控制文件读写内容的模式??
- 控制文件读写内容的方式有2种:t模式、b模式,它们都不可以单独使用,必须更r/w/a这种控制文件读写的方式连用。
- 强调:控制的是读入的是什么内容的格式,写入的是什么内容的格式。注意:并不是控制文件读写操作,而是控制文件读写内容,其必须要与操作文件的默认连用。
1、t:文本模式(默认的模式,默认的操作模式r)
- 强调1:读写都是以str为单位。(python3中str也可以直接看成unicode)
- 强调2:你的数据来源只能是文本文件(图片,视频都不适用)
- 强调3:必须指定编码的参数:encoding=‘utf-8‘
2、b:二进制模式
??控制文件读写操作的模式??
1、r:只读模式
"""
r模式是默认的操作模式:只读模式。当文件不存在时,r模式会报错。当文件存在时,文件指针跳到开始位置,也就是说从文件开头位置开始。只能读,不能写。
先手动创建c.txt文件文件,文件内容如下:
哈哈哈哈
"""
# 1、以t模式为基础进行内存操作
with open('c.txt', mode='rt', encoding='utf-8') as f:
print('res'.center(50, '-'))
res = f.read() # 执行f.read(),文件指针从开头一下子跳到文件末尾,同时也把文件内容一次性由硬盘读入内存。问题? 当文件过大时,会把内存干懵!!!
print(res)
print('res1'.center(50, '-'))
res1 = f.read() # 注意:上面执行了f.read()操作,文件指针在末尾,这个时候怎么读。都读不出来了。
print(res1)
# 注意:上面读出文件的每行内容,在每行内容末尾都有个换行符
。
'''
-----------------------res------------------------
哈哈哈哈
-----------------------res1-----------------------
'''
# 2、案例:化之前的用户登录操作,之前的用户站账户信息不能永久保存,这里我们通过存入文件将用户账户信息永久保存。网址连接(第9题:编写用户登录接口写法一):https://www.cnblogs.com/yang1333/p/12357167.html
# 经验总结:for+else,用于用户登录功能中时,else中的子代码块放用户登录失败以后的打印信息。要知道用户登录成功,一定是break退出循环,这个else错误信息也就不执行,也没有执行的必要。但是反过来说,用户登录失败,break语句也就一定不会执行到,那么else中的子代码块的执行,也就不会被break打段。
'''
先手动创建user.txt文件文件,文件内容如下:
egon:123
lili:456
jack:777
tom:666
'''
inp_username = input("please input your username>>:").strip()
inp_password = input("please input your password >>:").strip()
with open('user.txt', mode='rt', encoding='utf-8') as f:
for line in f: # 遍历文件对象,line取出的是文件中的每1行的内容。(注意:取出的内容都是str类型,且每一行的末尾都有换行符
,直接打印print(line)看不到,所以下面使用print([line])放入列表中显示)
# print([line])
# line.split() # 注意:不能直接使用split(),因为文件每行内容末尾(除了最后1行文件内容没有换行符)都有换行符
,我们要像下面??一样先使用strip()去除
。
res = line.strip() # 使用strip()默认不加参数,去除空白,需要注意的是
这个换行符也叫空白符,也可以去除。
# print([res])
# 使用split(':')切分字符串,转换成列表。第一个值作为用户账号,第二个值作为用户密码。
username, password = res.split(':')
if username == inp_username and password == inp_password:
print('登录成功!')
break
else:
print('登陆失败!账号或密码错误!')
2、w:只写模式
"""
w:只写模式,当文件不存在时,会创建空文件。当文件存在时,会清空文件。文件指针位于开始位置。不可读,只能写。
"""
with open('d.txt', mode='wt', encoding='utf-8') as f:
# f.read() # 不可读,只能写。
f.write('哈哈哈哈我擦嘞
') # 注意:每一次运行,在w模式下,都会先清空原内容。文件指针位于开始位置。(提示:这里的
是位-------)
'''
d.txt文件中显示结果:
哈哈哈哈我擦嘞
'''
# 强调1:w模式打开文件没有关闭的情况下,连续的写,新的内存总是更在旧的之后。
with open('d.txt', mode='wt', encoding='utf-8') as f:
f.write('我擦嘞1
')
f.write('我擦嘞2
')
f.write('我擦嘞3
')
'''
d.txt文件中显示结果:
我擦嘞1
我擦嘞2
我擦嘞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
')
# 以上内容,d.txt文件中,只有:我擦嘞3
# 案例:w模式用来创建全新文件(应用:文件与文件的copy工具)
import os
source_file = input("源文件路径>>:").strip()
destination_file = input("目标路径>>:").strip()
# 先判断源文件路径在不在,不在帮助用户在指定路径下创建源文件及其内容
if not os.path.isfile(source_file):
with open(r'{}'.format(source_file), mode='wt', encoding="utf-8") as f:
for i in range(4):
f.write('我擦嘞:%s
' % i)
with open(r'{}'.format(source_file), mode='rt', encoding='utf-8') as f, open(r'{}'.format(destination_file), mode='wt', encoding='utf-8') as f1:
# 将读出的源文件内容,写入用户指定的目标件中
# source_file_content = f.read()
# f1.write(source_file_content)
# 优化:??上面2步我们发现使用的是f.read(),它是一下子把文件从硬盘读入内存,如果文件过大,会把内存干懵逼!
for line in f:
f1.write(line)
'''
copy后目标文件内容:
我擦嘞:0
我擦嘞:1
我擦嘞:2
我擦嘞:3
'''
3、a:只追加写模式
- 这里总结了a模式与w模式区别以及a模式与w模式作用??:
"""
a:只追加写。在文件不存在时,会创建空文档,文件指针只能在开头,其实这里的开头也是末尾。在文件存在时,文件指针会直接跳到文件内容末尾。不能读,只能追加写。
a模式与w模式区别:
相同之处:在文件打开不关闭的情况下,连续的写入,新写的内容总会跟在之前写的内容之后。
不同之处:a模式重新开打文件,只要打开文件,它的指针就会跳到末尾。w模式重新打开文件,直接清空文件。
a模式与w模式作用:
w模式用来创建新文件。(通常用来copy文件)
a模式争对老文件。(通常用来记录日志文件,通常用与用户注册)
"""
with open('e.txt', mode='at', encoding='utf-8') as f:
f.write('我擦嘞1
')
f.write('我擦嘞2
')
f.write('我擦嘞3
')
# a模式案例:实现用户注册功能(每来一个用户,打开文件,把新用户的信息追加写到已存在的用户账户末尾。)
'''
提前创建user.txt文件,写入以下内容
egon:123
alex:alex3714
'''
# 或者使用下面方法快速创建
"""
import os
if not os.path.isfile('user.txt'):
with open(r'user.txt', mode='wt', encoding='utf-8') as f:
f.write('egon:123
alex:alex3714
')
"""
register = False
while True:
username = input('请输入注册账号>>:').strip()
password = input('请输入注册密码>>:').strip()
confirm_password = input('请确认注册密码>>:').strip()
# 如果username,password,confirm_password有一个为空那么让用户重新注册
if '' in [username, password, confirm_password]:
print('注册账号、注册密码、确认注册密码不能为空。')
continue
# 如果用户2次密码不一致,那么让用户重新注册
if password != confirm_password:
print('用户2次密码不一致')
continue
# 如果用户以及存在,那么让用户重新注册
with open(r'user.txt', mode='rt', encoding='utf-8') as f:
for line in f:
if username == line.strip().split(':')[0]:
print('用户已经存在,重新注册')
break
else:
register = True
print('正在为您注册中'.center(50, '-'))
import time
time.sleep(2)
if not register:
continue
# 用户注册满足条件,写入文件,注册该用户
with open(r'user.txt', mode='at', encoding="utf-8") as f:
f.write('{}:{}
'.format(username, password))
print('恭喜你!注册成功!'.center(50, '-'))
break
4、+:r+、w+、a+模式(注意:具体操作都受限于左侧的模式)-->了解
"""
注意:+不能单独使用,必须配合r、w、a
"""
# 1、r+模式:以r基准,g.txt文件不存在,直接就报错
'''
提前创建user.txt文件,写入以下内容:
111
222
333
444
5555
444
5555
中国
中国
中国
'''
with open('g.txt', mode='rt+', encoding='utf-8') as f:
print(f.read())
f.write('中国
') # 如果上面执行了f.read()操作,文件指针默认就会移动到文件末尾,f.write('中国
')操作就会把内容写入到文件末尾。(类似于a操作)如果上面没有执行f.read()操作,文件指针默认在开始位置,输入的内容多少,就会把g.txt中的原内容覆盖多少。
# 2、w+模式:以w基准
with open('h.txt', mode='w+t', encoding='utf-8') as f:
f.write('111
')
f.write('222
')
f.write('333
')
# w模式打开文件,清空源文件,文件指针在起始位置。以上f.write操作会按照先后顺序写入h.tx文件。
print('=======>', f.read())
# ??上面使用f.read()操作,这个时候文件指针在末尾,并不能读出任何内容。
# 3、a+模式:以a基准
with open('g.txt',mode='at+',encoding='utf-8') as f:
# print('f.read()') # a模式下,一打开文件,文件指针就在末尾。f.read()操作并不能读出任何文件内容。
f.write('中国') # 更具上面得知文件指针就在末尾,f.write操作会把输入的内容追加到文件内容的末尾去。
四、文件操作的方法
- 文件操作的方法主要就是争对读/写
1、重点
2、了解
五、文件高级操作:控制文件指针的移动
1、案例一: 0模式详解
3、案例二: 1模式详解
3、案例三: 2模式详解
六、文件的修改的两种方式
1、文件修改方式一
2、文件修改方式二
以上是关于01 文件处理的主要内容,如果未能解决你的问题,请参考以下文章
Oracle 数据库 - 使用UEStudio修改dmp文件版本号,解决imp命令恢复的数据库与dmp本地文件版本号不匹配导致的导入失败问题,“ORACLE error 12547”问题处理(代码片段