python基础学习-文件其他操作模式(补充)

今日内容:

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('哈哈\n')

控制文件读写内容的模式
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\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

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)
posted @ 2020-03-16 16:20  sunshine如你  阅读(314)  评论(0编辑  收藏  举报