今日内容:
1、文件模式
x模式: x,只写模式(不可读;文件不存在则创建,文件存在则报错)
with open('a.txt',mode='x',encoding='utf-8') as f:#如果a.txt文件已经创建,则报错
pass
with open('b.txt',mode='x',encoding='utf-8') as f:
f.read() #报错,x模式不可读
with open('c.txt',mode='x',encoding='utf-8') as f:
f.write('哈哈
')
控制文件读写内容的模式
t:(模式只能读文本文件)
1.读写都是以字符串(unicode)为单位
2.只能针对文本文件
3.必须制定字符编码,即必须指定encoding参数
b:binary模式(可以对任何数据进行操作,MP4,jpg,txt....)
1.读写都是以bytes为单位
2.可以针对所有文件
3.一定不能指定字符编码
错误演示:t模式只能读文本文件
with open('爱情.mp4',mode='rt') as f:#这步只是打开文件,不会报错
f.read() #硬盘的二进制读入内存--t模式会将读入内存的内容进行decode解码,这个时候会出错
with open('爱情.mp4',mode='rb') as f: #binary二进制模式读写都是以bytes为单位,所以不用指定编码模式
res=f.read() #硬盘的二进制读入内存--b模式下,不做任何转换,直接读入内存
print(res) #bytes类型--当成二进制
2、文件的操作的其他方法
大文件拷贝案例,用循环方式读取
扩展:###大文件的拷贝!!!
方法一:
#大文件的数据都是存储在内存里面,需要防止内存溢出
#原文件的名字
file_name="test.jpg"
new_file_name,point,end_str=file_name.rpartition(".")
print(new_file_name)
print(point)
print(end_str)
dst_file_name=new_file_name+"[复件]"+point+end_str
print(dst_file_name)
dst_file=open(dst_file_name,"wb")
file=open(file_name,"rb")
#循环读取数据时采用循环读取(每次占用的空间只是新读取的数据,之前的数据会在内存中释放)
while True:
file_data = file.read(1024)#循环读取1024个字节的数据,可以指定读取数据的长度
if len(file_data)>0:# if not file_data: #判断是否为空,不为空就写入目标文件里面
print("读出的数据为:",file_data)
dst_file.write(file_data)
else:
print("文件拷贝完毕!")
break
#注意:再进行大文件拷贝时,特别要注意写数据的地方,需要循环写入,防止一次性写入文件数据过大而导致内存溢出!!!
dst_file.close()
file.close()
方法二:
#循环读取文件
src_file=input('源文件路径>>: ').strip()
dst_file=input('源文件路径>>: ').strip()
with open(r'{}'.format(src_file),mode='rb') as f1,
open(r'{}'.format(dst_file),mode='wb') as f2:
while True:
res = f1.read(1024)#循环读取1024个字节的数据,可以指定读取数据的长度
if len(res)>0:# if not file_data: #判断是否为空,不为空就写入目标文件里面
print("读出的数据为:",res)
f2.write(res)
else:
print("文件拷贝完毕!")
break
应用:文件拷贝工具
src_file=input('源文件路径>>: ').strip()
dst_file=input('源文件路径>>: ').strip()
with open(r'{}'.format(src_file),mode='rb') as f1,
open(r'{}'.format(dst_file),mode='wb') as f2:
#res=f1.read() # 内存占用过大
#f2.write(res)
for line in f1:
f2.write(line)
3、文件的高级操作:控制文件指针的移动
3.1 读相关操作
res=f.readline() #一行一行读取数据
while Ture:
line=f.readline()
if line(line)==0:
break
print(line)
res=f.readlines() # 把数据都一行行读取出来放入一个列表里输出
#强调:这两种方式都是键数据一次性读入内存,如果数据内存过大容易造成内存溢出
3.2 写相关操作
f.writelines() #相当于调了一个for循环
with open('c.txt',mode='wt',encoding='utf-8') as f:
l=['111
','2222','33333']
for line in l:
f.write(line)
#以上可以用 f.writelines()实现
f.writelines(l)
#如果将写入模式变成 wb模式 就出错了,可以在列表里面指定编码模式处理,就可以用writelines
with open('c.txt',mode='wb',encoding='utf-8') as f:
l=[
'111
'.encode('utf-8'),
'2222'.encode('utf-8'),
'33333'.encode('utf-8')
]
f.writelines(l)
补充1:如果是纯英文字符,可以直接加前缀b得到bytes类型
l = [
b'1111aaa1
',
b'222bb2',
b'33eee33'
]
补充2:'上'.encode('utf-8') 等同于bytes('上',encoding='utf-8')
l = [
bytes('上啊', encoding='utf-8'),
bytes('冲呀', encoding='utf-8'),
bytes('小垃圾们', encoding='utf-8'),
]
f.writelines(l)
以下用法了解:
with open('h.txt',mode='wb',encoding='utf-8') as f:
f.write() #将数据从内存写入硬盘上,将数据都攒够了再写入
f.flush() #每次都直接写入到硬盘,立马运过去
f.readable() # 文件是否可读
f.writable() # 文件是否可读
f.closed # 文件是否关闭
f.encoding # 如果文件打开模式为b,则没有该属性
f.flush() # 立刻将文件内容从内存刷到硬盘
f.name
3.3 控制指针的移动
指针移动的单位都是以bytes/字节为单位
只有一个情况特殊:
t模式下的read(n),n代表的是字符个数
with open('aaa.txt',mode='rt',encoding='utf-8') as f: #aaa文件存放 abc你好嘛
res=f.read(4)
print(res) #读出 abc你
其他情况都是字节为单位
f.seek(n,模式):n指的是移动的字节个数
模式:
0:参照物是文件开头位置
f.seek(9,0)
f.seek(3,0) #3
1:参照物是当前指针所在的位置
f.seek(9,1)
f.seek(3,1) #12
2:参照物是文件末尾位置,应该是倒着移动
f.seek(-9,2) #3
f.seek(-3,2) #9
##强调:!! 只有0模式可以在t下使用,1、2必须在b模式下用
f.tell()#获取文件指针当前位置
举例
with open('aaa.txt',mode='rb',) as f:
f.seek(9,0)
f.seek(3,0)
print(f.tell()) #3
res=f.read()
print(res.decode('utf-8')) #你好
with open('aaa.txt',mode='rb',) as f:
f.seek(9,1)
f.seek(3,1)
print(f.tell())
res=f.read()
print(res.decode('utf-8'))
with open('aaa.txt',mode='rb',) as f:
f.seek(-9,2)
f.seek(-3,2)
print(f.tell())
print(f.read().decode('utf-8')) #好
3.4 文件的修改方式有2种
1、文件修改方式一
文本编辑采用的就是这种方式
实现思路:将文件内容发一次性全部读入内存,然后在内存中修改完毕后再覆盖写回原文件
优点: 在文件修改过程中同一份数据只有一份
缺点: 会过多地占用内存
with open('a.txt',mode='rt',encoding='utf-8') as f:
res=f.read()
data=res.replace('alex','dsb')
print(data)
with open('a.txt',mode='wt',encoding='utf-8') as f1:
f1.write(data)
2、 文件修改方式二
实现思路:以读的方式打开原文件,以写的方式打开一个临时文件,一行行读取原文件内容,修改完后写入临时文件...,删掉原文件,将临时文件重命名原文件名
优点: 不会占用过多的内存
缺点: 在文件修改过程中同一份数据存了两份
with open('a.txt', mode='rt', encoding='utf-8') as f,
open('.a.txt.swap', mode='wt', encoding='utf-8') as f1:
for line in f:
f1.write(line.replace('alex', 'dsb'))
os.remove('a.txt')
os.rename('.a.txt.swap', 'a.txt')
f = open('a.txt')
res = f.read()
print(res)