python之路----文件2

文件处理模式---b模式

      1.与 t 模式类似,只能与a,r,w连用

      2.能打开图片文件.文本文件...不同于t模式的局限性,获得的为bytes类型,不能指定字符编码

      3.打开文本文件与图片文件所获得的bytes不同

with open('1.jpg','rb') as f:
	data=f.read()
	print(data)
	print(data.decode('utf-8'))
#--->UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
#图片的Bytes不能字符编码
 with open('a.txt','rb') as f:
	data=f.read()
	print(data)
	print(data.decode('utf-8'))   
#--->b'\xe5\x95\x8a\xe5\x95\x8a\xe5\x95\x8a\xe5\x95\x8a\xe5\x95\x8a\xe5\x95\x8a'
#直接将数据从硬盘加载到内存中(不经过字符编码,直接得到utf-8编码格式的二进制)
#--->  啊啊啊啊啊啊
#将utf-8格式的二进制解码成unicde形式

a+,r+,w+:可读可写

 文件内容:

你瞅啥
你愁啥
哈哈哈
with open('a.txt','r+t',encoding='utf-8') as f:
    line=f.readline()
    print(line)
    f.write('\n我在哪?')

执行上面代码,

       以r模式打开文件时,光标跑到文件开头,readline()读取一行,f.write()基于光标此时位置写入

but  ---->执行结果:

你瞅啥
你愁啥
哈哈哈
我在哪?

哈?在写入数据的时候光标跑到了最后---->原因:这与数据在硬盘上的存储原理有关

从文件直观的角度看,我们插入数据是将插入内容后的所有数据统统后移,然而,硬盘是基于磁工作的,一圈圈写入数据,这咋移?

文件内容:

你好hello

 执行代码--->

with open('a.txt','r+t',encoding='utf-8') as f:
     f.seek(3)
     f.write('哈哈')
执行结果--->你哈哈lo  
对 '好hel' 造成了覆盖
注:
  with open('a.txt','r+t',encoding='utf-8') as f:
     f.seek(3)
     f.write('s')
执行结果--->你s��hello
s只覆盖了好这个字符的一个字节

注:如果在文件打开的时候不指定encoding可能会报错,原因是:

    1.f =opne('') --->给操作系统发送请求,并接受文件操作接口

    2.在未指定字符编码的情况下,win操作系统使用默认的字符编码(gbk)解码硬盘中的utf-8格式(之前以utf-8格式写入的),

这又是数据读取字符编码不一致导致。

 文件的修改:

   基础知识:硬盘上的数据是不能被修改的(基于磁写数据),只能是新数据覆盖原数据达到删除效果

       1.例如对于文件系统:拥有super block(相对于一家之长),innode block(储存文件源数据:权限....指针),direcotry block(目录块,用于储存文件的映射关系:a.txt  ----->a.txt的innode号) ,block块(用于储存数据)

      2.查找一个E:\a.txt文件,从过程来看:系统先找到E:\的innode号,根据源数据内的指针------>找到direcotry block,得到a.txt的innode号,再根据innode号找到block块:获取数据

      3.删除一个a.txt文件,从过程来看:1.先在super block上标记a.txt的innode号为free状态,2.切断direcotry block块中的对应关系.3.在block储存块中标记储存a.txt的block为free空闲状态(数据仍存在)  等到下次有文件b.txt要写入硬盘时,super block块随机将原a.txt的innode号分配给b.txt造成覆盖(也有可能没有分配出去,因此重新建立关系,就可能恢复数据)

修改文件的两种方法:

        1.-------->a.先将文件内容全部读到内存中

                       b.在内存中完成修改         

                       c..将修改后的内容覆盖到原文件 (不适用修改过大的文件)

      优点:在文件修改过程中不会占用两份硬盘资源

      缺点:在修改文件的时候,一次性的将文件读入,过大的文件会使内存...

原文件内容
1111
2222
3333
with open('test.txt','r',encoding='utf-8') as f:
    data=f.read()
    data=data.replace('3333','1111')
with open('test.txt','w',encoding='utf-8') as f:
    f.write(data)
修改后的文件
1111
2222
1111


        2.--------->a..以只读的方式打开原文件,以写的方式打开新文件

                        b.按行的方式读文件

                        c.判断,如果为需要修改的文件内容,则替换,否则,保持原文件内容,按行写入

                        d.删除原文件,将新文件命名为原文件.      

      优点:同一时刻在内存中只存在原文件的一行数据,不会过多的占用内存资源

      缺点:在修改文件的时候,在硬盘中会存在两份相同数据文件(原文件和目标文件)

原文件内容
bob 123456789 00
tom 123456789 11
jam 123456789 22

import os
with open('test.txt','r',encoding='utf-8') as f, \
        open('test2.txt', 'a', encoding='utf-8') as f1:
    for line in f:
            if 'tom'in line:
               line=line.replace('tom','tomx')
            f1.write(line)
os.remove('test.txt')
os.rename('test2.txt','test.txt')


新文件内容
bob 123456789 00
tomx 123456789 11
jam 123456789 22

猜你喜欢

转载自blog.csdn.net/ltfdsy/article/details/81154088