day5-python的文件操作-坚持就好
目录摘要
文件处理
1.文件初识
2.文件的读操作
3.文件的写操作
4.文件的追加操作
5.文件的其他操作
6.文件的修改
正式开始
文件处理:写了这么多代码了,有的时候我们执行完成的结果想永久保存或者是保存后方便下一次在调用,对于文件的主要操作就是读,写以及追加了。
1.文件初识
现在我们有一个文件,现在通过python代码打开这个文件,而打开这个文件,就有了必须的三要素
path:文件的路径
mode:操作类型,r w r+ w+ a……
encoding: 编码类型 一般的unicode gbk gb2312等
一般读取的时候报错的原因:
1.1 路径错误:\与后面的那个字符具有了特殊意义。
解决办法:
r’d:\test文件.txt’在路径最前方加r,表明这个是一个完整的路径
‘d:\\test文件.txt’对第一个\进行转义,表明他是一个\
1.2 unicodedecodeerror:编码错误
打开文件的编码与文件的编码不一致
1.3 encoding只是声明了这个文件需要用什么编码编译
1.4 路径
绝对路径:从磁盘根目录开始,找到文件的具体路径。
相对路径:从当前路径(当前文件夹)找到的文件的路径
2.文件的读操作
2.1 文件读操作的定义与基本解释,具体查看下方示例
示例一:
f = open(file='D:\pycharm\全栈三期\day6\作业.txt',mode='r',encoding='utf-8') data = f.read() f.close() #上述就是一个文件读取最完整的表述
f f1 file file_handle f_h等,都称之为文件句柄
open() python的内置函数,但是实际上是调用的操作系统对文件操作的功能#windows默认是GBK编码,Linux与MACos 默认使用utf-8编码
####对文件的任何操作都是借助文件句柄进行操作####
file= '文件的绝对路径' mode ='对于文件的操作模式' encoding = '文件的编码格式',此处的encoding必须和文件写入时的文件编码格式一致,要不然就会报错 #然后将读取的文件的内容赋值给一个变量 #!!!!# 很重要的是对于一个文件操作后一定要对文件关闭,一定要关闭文件句柄
2.2 ’r‘的五种读取方式
2.2.1 r.read()全部读出来
f1 = open('作业.txt','r',encoding='utf-8') data = f1.read() print(data)
f1.close() #结果 我们的作业啊~~~~~! 我们的作业还有很多!!! #全部读取出来
2.2.2 r.read(n)读几个字符
f1 = open('作业.txt','r',encoding='utf-8') data = f1.read(3) print(data)
f1.close() #结果 我们的 #我们会发现输入3并不是读取三个字节,而是三个字符
2.2.3 r.readline()读一行
f1 = open('作业.txt','r',encoding='utf-8') print(f1.readline()) print(f1.readline())
f1.close() #结果 我们的作业啊~~~~~! 我们的作业还有很多!!! #这样就是一行一行读取,不过一行只能读取一次
2.2.4 r.readlines()全部读取,返回一个列表
f1 = open('作业.txt','r',encoding='utf-8') data = f1.readlines() print(data)
f1.close() #结果 ['我们的作业啊~~~~~!\n', '我们的作业还有很多!!!'] #会发现生成的文件句柄是一个列表,然后循环这个文件,就会逐行打印
2.2.5 for循环的读取
f1 = open('作业.txt','r',encoding='utf-8') for line in f1: print(line)
f1.close() #结果 我们的作业啊~~~~~! 我们的作业还有很多!!!
总结:文件读取有以上五种情况,不过对于前四种,如果文件比较小,则使用前四种一点问题都没有,可是如果是一个大文件读取,一次性读取一个大容量文件,内存绝对会撑爆,对于这种文件操作,一般是将文件生成一个迭代器,一行一行的去读取,这样内存占用就会小很多了。
2.3 rb模式
对于rb,我们需要知道一点,b模式操作的文件是非文字类的文件:图片,音频,视频等
f = open('作业.txt','rb') data = f.read() print(data) #结果 b'\xe6\x88\x91\xe4\xbb\xac\xe7\x9a\x84\xe4\xbd\x9c\xe4\xb8\x9a\xe5\x95\x8a~~~~~\xef\xbc\x81\r\n\xe6\x88\x91\xe4\xbb\xac\xe7\x9a\x84\xe4\xbd\x9c\xe4\xb8\x9a\xe8\xbf\x98\xe6\x9c\x89\xe5\xbe\x88\xe5\xa4\x9a\xef\xbc\x81\xef\xbc\x81\xef\xbc\x81' #生成的结果就是上面这么一串字符串
f = open('作业.txt','rb')
data = f.read(3)
print(data)
f.close()
#结果
b'\xe6\x88\x91'
由上面这个示例,可以看出,
在r模式下,read(n)是按照字符来移动
在rb模式下,read(n)就是按照字节来移动,并不是字符了
rb的格式是以二进制的方式的读取文件,文件在硬盘中存储方式为010101010,则rb就是将文件安装二进制的方式读取出来,如果需要转换在使用encoding进行编码
2.4 r+读写模式
对于读写模式,我们可以理解为先读后写,在追加
f1 = open('作业.txt','r+',encoding='utf-8') data = f1.read() f1.write('今天还要加油鸭!') print(data) f1.close()
结果为
如果我们非要先写后读呢,看示例
f1 = open('作业.txt','r+',encoding='utf-8') f1.write('今天还要加油鸭!') data = f1.read() print(data) f1.close()
结果呢就变成下面这个样子
和上面的相比,我们写的内容就会覆盖文件中第一行,并没有起到追加的效果,这个时候就需要一个提到一个指针的概念,这个在后面文件的其他应用中说明。需要谨记的是在r+模式中,应该先读在写的
3.文件的写操作
3.1 w操作
这个时候你一定要记得,w就是就将文件重新写一遍,以前的内容全部都没有了!!!!
文件的写操作,是没有文件则创建文件,有文件则会先清空内容在写入新内容
w模式下,必须是以字符串的内容写入,不过需要记住的是文件的写操作是可以持续写的
#第一种
f = open(file='作业.txt',mode='w',encoding='utf-8') f.write('我们的作业啊~~~~~!') f.close() #file= '文件打开的相对路径' #mode = '打开的文件方式为写' #encoding ='编码格式'
#第二种
f1 = open('作业.txt','w',encoding='utf-8')
f1.write('我爱写作业')
f1.write('我爱写作业')
f1.write('我爱写作业')
f1.write('我爱写作业')
f1.write('我爱写作业')
f1.write('苦笑!')
f1.close()
运行结果就是这样子,以前的内容全部都没有了,慎重使用
注意:
文件操作时,以 “w”或“wb” 模式打开,则只能写,并且在打开的同时会先将内容清空。
写入到硬盘上时,必须是某种编码的0101010,打开时需要注意:
wb,写入时需要直接传入以某种编码的0100101,即:字节类型
w 和 encoding,写入时需要传入unicode字符串,内部会根据encoding制定的编码将unicode字符串转换为该编码的 010101010
3.2 wb操作
rb和wb一般都是用在非文本的文件中,例如图片,音频和视频等
f = open('百度.jpg','rb') coment = f.read() f.close() f1 = open('百度1.jpg','wb') f1.write(coment) f1.close() #结果会看到在相同文件中看到一样的图片
3.3 w+操作
w+操作就是写读模式
f1 = open('作业.txt','w+',encoding='utf-8') f1.write('啊啊啊啊啊啊啊~~~') f1.write('啊啊啊啊啊啊啊~~~') f1.write('啊啊啊啊啊啊啊~~~') f1.write('啊啊啊啊啊啊啊~~~') f1.seek(0) print(f1.read()) #结果 啊啊啊啊啊啊啊~~~啊啊啊啊啊啊啊~~~啊啊啊啊啊啊啊~~~啊啊啊啊啊啊啊~~~ #就会发现,会先将之前的文件全部清空,清空后再赋值,然后将光标放在第一位,才能读取出来,这个一般真的不用
4.文件的追加操作
输出结果
f = open(file='作业.txt',mode='a',encoding='utf-8') f.write('\n我们的作业还有很多!!!') f.close() #文件的追加,就是在文件的最后一行追加一行,并不改变文件本身的内容
用追加模式,没有文件则创建文件追加内容,有文件的则会在文件的末尾追加内容
注意:
文件操作时,以 “a”或“ab” 模式打开,则只能追加,即:在原来内容的尾部追加内容
写入到硬盘上时,必须是某种编码的0101010,打开时需要注意:
ab,写入时需要直接传入以某种编码的0100101,即:字节类型
a 和 encoding,写入时需要传入unicode字符串,内部会根据encoding制定的编码将unicode字符串转换为该编码的 010101010
5.文件的其他操作
readable writeable 判断一个句柄是否可读,可写
f = open('作业.txt','w',encoding='utf-8') print(f.readable()) print(f.writable()) #结果 False True #返回的是布尔值
seek tell 将光标移动到一个特定的位置 判断一个文件现在光标的位置
f = open('作业.txt','r+',encoding='utf-8') print(f.read()) f.seek(3)#指针迁移是按照字节迁移,因为用utf-8编码,所以一个字符就是三个字节 print(f.read()) f.seek(0,2)#将指针末尾 print(f.tell()) f.close() #结果 凉州词 黄河远山白云间 一片孤城万仞山 羌笛何须怨杨柳 春风不度玉门关 州词 黄河远山白云间 一片孤城万仞山 羌笛何须怨杨柳 春风不度玉门关 101#光标位置
flush 将内存中的内容强制刷新到磁盘内
f2 = open('file4',encoding='utf-8',mode='w') f2.write('老男孩教育是最好的学校') f2.flush() # 强制保存 相当于ctrl + s f2.close()
trunkcate 在可写的模式下,截取原文件,只能从头截取,不能调整光标去截取一部分
# f2 = open('file4',encoding='utf-8',mode='w') # f2.write('老男孩教育是最好的学校') # f2.flush() # 强制保存 相当于ctrl + s # f2.close() # 不能在w模式下使用truncate # f1 = open('file4', encoding='utf-8',mode='w') # f1.truncate(6) # f1.close()
补充用法:如果不知道文件的编码格式,也可以,不过这个时候需要导入其他模块
f = open('作业.txt',mode='rb') data = f.read() f.close() result = chardet.detect(data) print(result) #结果 {'encoding': 'UTF-8-SIG', 'confidence': 1.0, 'language': ''} #其中confidence:1.0 表示100%肯定为utf-8编码的文件
#简单的文本文档逐行打印
f = open('作业.txt',mode='r',encoding='utf-8')
for line in f:
print(line)
6.文件的修改
6.1 文件打开的另一种方式
除了上文中的打开方式之外,还有另外一种方式,相比于上面的方式,有一些其他的特点:
- 自动关闭文件的句柄
- 同一语句可以操作创建多个文件句柄
with open('作业.txt','r',encoding='utf-8')as f1, \ open('百度.jpg','rb',): for line in f1: print(line.strip()) #结果 凉州词 黄河远山白云间 一片孤城万仞山 羌笛何须怨杨柳 春风不度玉门关
虽然用with是可以自动关闭文件句柄,如果持续将一个文件产生俩次文件句柄,很有可能发生IO错误,还是需要谨记的。
6.2 文件的修改
现有的文件编辑软件,例如office,wps这些文本操作软件他们对于文件编辑的操作方式如下
- 以读的模式打开原文件,产生文件句柄f1
- 以写的模式打开新文件,产生文件句柄f2
- 读取原文件,将原文件的内容改写至新文件内
- 删除原文件
- 将文件重命名为原文件
现有这么案例,将文本中’alex‘全部改写为’SB’:
log内
alex是老男孩python发起人,创建人。
alex其实是人妖。
谁说alex是sb?
你们真逗,alex再牛逼,也掩饰不住资深屌丝的气质。
方式一:
import os with open('log','r',encoding='utf-8')as f1,\ open('log.bak','w',encoding= 'utf-8')as f2: old_data = f1.read() new_data = old_data.replace('alex','SB') f2.write(new_data) os.remove('log') os.rename('log.bak','log') #结果 SB是老男孩python发起人,创建人。 SB其实是人妖。 谁说SB是sb? 你们真逗,SB再牛逼,也掩饰不住资深屌丝的气质。
方式二:升级一下,现在文件内容比较少,如果内容多了额,一下就撑爆内存了,改进下,用for循环的方式
import os with open('log','r',encoding='utf-8')as f1,\ open('log.bak','w',encoding='utf-8')as f2: for line in f1: line = line.replace('alex','SB') f2.write(line) os.remove('log') os.rename('log.bak','log') #结果 SB是老男孩python发起人,创建人。 SB其实是人妖。 谁说SB是sb? 你们真逗,SB再牛逼,也掩饰不住资深屌丝的气质。 对于大文件还是推荐这么用,不过对于小文件就无所谓了,反正也占用不了太多内存
最后总结一下,对于文件操作是python中的一种基本操作,其中,主要用r r+ 其次用rb w wb a
带b的模式都是操作非文本类的文件,例如图片音频和视频
文件操作中比较常用的为readable writable flush tell seek