引子:
应用程序运行过程中产生的数据最先都是存放于内存中的,若想永久保存下来,必须要保存于硬盘中。应用程序若想操作硬件必须通过操作系统,而文件就是操作系统提供给应用程序来操作硬盘的虚拟概念,用户或应用程序对文件的操作,就是向操作系统发起调用,然后由操作系统完成对硬盘的具体操作。
.txt 没有后缀名的文件,numpy、pandas等模块可以操作。
我们现在不能操作word、excel、PPT等文件暂时不能够操作
'''
三步法:
1.打开文件(open)
2.读或者写
3.关闭文件
'''
open('要操作的文件路径','读写模式','字符编码')
1. 打开文件,由应用程序向操作系统发起系统调用open(...),
操作系统打开该文件,对应一块硬盘空间,并返回一个文件对象赋值给一个变量f
f=open('a.txt','r',encoding='utf-8') #默认打开模式就为r
2. 调用文件对象下的读/写方法,会被操作系统转换为读/写硬盘的操作
data=f.read()
3. 向操作系统发起关闭文件的请求,回收系统资源
f.close()
当路径中出现了字母和斜杠的组合会产生一些特殊的含义,所以我们应该给去掉:
r‘E:\Pycharm Project Test\_1Month_01\info.txt’。
'''open('要操作的文件路径', '读写模式', '字符编码')'''
1.方法一:
open('info.txt')
f= open(r'E:\Pycharm Project Test\_1Month_01\info.txt, 'r', \
encoding='utf-8') # \n \t
返回的是文件句柄
print(f)
#<_io.TextIOWrapper name='E:\\Pycharm Project Test\\_1Month_01\\info.txt'
#mode='r' encoding='utf-8'>
读取文件
# helloworld
print(f.read()) # 类似于是文件的内置方法
关闭文件
f.close()
2.方法二
'''
# with上下文管理器打开文件!
# as:起别名
# 它的特点就在于:能够自动关闭文件
'''
with open('info.txt','r', encoding='utf-8') as f:
print(f.read())
# f=open('info.txt', 'r', encoding='utf-8') f.close()
'''
语法格式:
open(文件路径,读写模式,字符编码)
文件路径:是必须写的
读写模式:也是必须写的
字符编码:可选的
'''
读写模式:
>r(只读:只能读不能写) w(只写:只能写,不能读)
>a(append:在原来的基础之上在添加新的内容)
'''当文件路径不存在的时候,会直接报错'''
# f = open('b.txt','r',encoding='utf-8')
'''No such file or directory: 'b.txt'''
f = open('info.txt', 'r', encoding='utf-8')
print(f.read())
f.close()
with open('info.txt','r',encoding='utf-8') as f:
print(f.read())
"""写模式的特征:
1. 当文件路径不存在的时候, 会新建出来一个文件,而不报错
2. 当文件存在的时候会清空文件,文件指针跑到文件开头
"""
with open('info.txt','w',encoding='utf-8') as f :
# pass #为了补全语法结构
f.write('hello,world') #这里就已经写进去info.txt文件里面了
'''这里是第二次写入'''
f.write('good morning')# 它会把第一次的数据全删掉,然后在写这两次的数据
'''
#强调:
# 1 在文件不关闭的情况下,连续的写入,后写的内容一定跟在前写内容的后面
# 2 如果重新以w模式打开文件,则会清空文件内容
'''
"""
追加模式:
当路径不存在的时候,也会新建出来文件
记住:它是追加写,而不是覆盖原来的内容!
"""
with open('info.txt','a', encoding='utf-8') as f :
f.write('hello,world\n')
f.write('good,morning\n')
'''
强调 w 模式与 a 模式的异同:
1 相同点:在打开的文件不关闭的情况下,连续的写入,
新写的内容总会跟在前写的内容之后
2 不同点:以 a 模式重新打开文件,不会清空原文件内容,
会将文件指针直接移动到文件末尾,新写的内容永远写在最后
'''
大前提: tb模式均不能单独使用,必须与r/w/a之一结合使用
t(默认的):文本模式(text)
1. 读写文件都是以字符串为单位的
2. 只能针对文本文件
3. 必须指定encoding参数
b:二进制模式:(binary)
1.读写文件都是以bytes/二进制为单位的
2. 可以针对所有文件
3. 一定不能指定encoding参数
t模式:如果我们指定的文件打开模式为r/w/a,其实默认就是rt/wt/at
with open('a.txt',mode='rt',encoding='utf-8') as f:
res=f.read()
print(type(res)) # 输出结果为:
with open('a.txt',mode='wt',encoding='utf-8') as f:
s='abc'
f.write(s) # 写入的也必须是字符串类型
强调:t模式只能用于操作文本文件,无论读写,都应该以字符串为单位,
而存取硬盘本质都是二进制的形式,当指定 t 模式时,内部帮我们做了编码与解码
b: 读写都是以二进制位单位
with open('1.mp4',mode='rb') as f:
data=f.read()
print(type(data)) # 输出结果为:
with open('a.txt',mode='wb') as f:
msg="你好"
res=msg.encode('utf-8') # res为bytes类型
f.write(res) # 在b模式下写入文件的只能是bytes类型
强调:b模式对比t模式
1、在操作纯文本文件方面t模式帮我们省去了编码与解码的环节,
b模式则需要手动编码与解码,所以此时t模式更为方便
2、针对非文本文件(如图片、视频、音频等)只能使用b模式
with open('info.txt','r',encoding='utf-8') as f:
print(f.read()) # read方法是一次性读取文件中得所有数据
print(f.readline()) # readline一次只读文件的一行内容
print(f.readlines()) # 一次性读取文件的所有内容,然后把每个内容作为列表
# 的一个元素返回,返回的数据类型为列表
print(f.readable()) # True
'''
强调:
f.read()与f.readlines()都是将内容一次性读入内容,
如果内容过大会导致内存溢出,若还想将内容全读入内存,
则必须分多次读入,有两种实现方式:
'''
1.方法一
with open('info.txt',mode='rt',encoding='utf-8') as f :
for line in f:
print(line) # 同一时刻只读入一行内容到内存中
2.方法二
with open('info.txt',mode='rb') as f:
while True:
date = f.read(1024) # 同一时刻只读入1024哥bytes到内存中
if len(date) == 0:
break
print(date)
'''了解的方法'''
f.flush() # 把数据从内存中立刻刷到磁盘
"""
当你读取的数据比较小的时候,其实是在缓冲区的,当数据量够多的时候,
它会一定刷到磁盘
"""
"""
一次性读取文件的所有数据有什么问题:
当数据比较多的时候,会出现内存溢出,这种情况是坚决不能出现的
如何优化以上操作:
一点一点的读取数据然后把数据赶紧刷到硬盘里
"""
with open('info.txt','w',encoding='utf-8') as f :
f.write('hello tom,good morning!\n') # 针对文本模式的写,需要自己写换行符
f.writelines(['333\n','444\n']) # 文件模式
大前提:文件内指针的移动都是Bytes为单位的,唯一例外的是t模式下的read(n),n为字符单位
with open('info.txt','r',encoding='utf-8') as f:
print(f.read(3)) # 读取3个字符
with open('info.txt','rb') as f:
print(f.read(3)) # 读取三个字节
之前文件内指针的移动都是由读/写操作而被动触发的,若想读取文件某一特定位置的数据,
则则需要用f.seek方法主动控制文件内指针的移动,详细用法如下:
f.seek(指针移动的字节数,模式控制):
模式控制:
0: 默认的模式,该模式代表指针移动的字节数是以文件开头为参照的
1: 该模式代表指针移动的字节数是以当前所在的位置为参照的
2: 该模式代表指针移动的字节数是以文件末尾的位置为参照的
强调:其中0模式可以在t或者b模式使用,而1跟2模式只能在b模式下用
with open('info.txt','r',encoding='utf-8') as f:
# print(f.read(3)) # 读取三个字符
f.seek(3,0) # 默认不写第二个数字的时候也是0
print(f.read())
print(f.read(5))
'''1/2模式仅支持b模式,二进制模式'''
with open('info.txt','rb') as f1:
print(f1.read(3)) # 读取三个字节(bytes)
print(f1.seek(3,1))
f1.seek(3,1) # 第一个数字代表着显示多少字节,第二个数字是以当前所在的位置为参照
print(f1.read())
f1.seek(-3,2)
print(f1.read())
print(f1.read(5))
mode='r+'(可读可写) mode='w+t'(可读可写) mode='a+t'(可读可写)
文件a.txt内容如下
张一蛋 山东 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、内存中的数据是可以修改的
实现思路:将文件内容发一次性全部读入内存,然后在内存中修改完毕后再覆盖写回原文件
优点: 在文件修改过程中同一份数据只有一份
缺点: 会过多地占用内存
with open('db.txt',mode='rt',encoding='utf-8') as f:
data=f.read()
with open('db.txt',mode='wt',encoding='utf-8') as f:
f.write(data.replace('kevin','SB'))
实现思路:以读的方式打开原文件,以写的方式打开一个临时文件,一行行读取原文件内容,
修改完后写入临时文件...,删掉原文件,将临时文件重命名原文件名
优点: 不会占用过多的内存
缺点: 在文件修改过程中同一份数据存了两份
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:
for line in read_f:
wrife_f.write(line.replace('SB','kevin'))
os.remove('db.txt')
os.rename('.db.txt.swap','db.txt')