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('哈哈\n')
控制文件读写内容的模式
t:(模式只能读文本文件)
1.读写都是以字符串(unicode)为单位
2.只能针对文本文件
3.必须制定字符编码,即必须指定encoding参数
b:binary模式(可以对任何数据进行操作,MP4,jpg,txt....)
1.读写都是以bytes为单位
2.可以针对所有文件
3.一定不能指定字符编码
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类型--当成二进制
大文件拷贝案例,用循环方式读取
扩展:###大文件的拷贝!!!
方法一:
#大文件的数据都是存储在内存里面,需要防止内存溢出
#原文件的名字
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)
res=f.readline() #一行一行读取数据
while Ture:
line=f.readline()
if line(line)==0:
break
print(line)
res=f.readlines() # 把数据都一行行读取出来放入一个列表里输出
#强调:这两种方式都是键数据一次性读入内存,如果数据内存过大容易造成内存溢出
f.writelines() #相当于调了一个for循环
with open('c.txt',mode='wt',encoding='utf-8') as f:
l=['111\n','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\n'.encode('utf-8'),
'2222'.encode('utf-8'),
'33333'.encode('utf-8')
]
f.writelines(l)
补充1:如果是纯英文字符,可以直接加前缀b得到bytes类型
l = [
b'1111aaa1\n',
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
指针移动的单位都是以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')) #好
原文:https://www.cnblogs.com/dingbei/p/12504640.html