Python的文件操作
一. 初识Python文件操作
使用python来读写文件是非常简单的操作. 我们使用open()函数来打开一个文件, 获取到文件句柄. 然后通过文件句柄就可以进行各种各样的操作了,
根据打开文件模式不同能够执行的操作也会有相应的差异。
二,文件的模式: r(只读)w(只写)a(追加) r+(读写)w+(写读)a+(追加写读)rb, wb, ab, r+b, w+b, a+b 默认使用的是r(只读)
模式的函数
open(文件名(路径), mode="模式", encoding="编码集"("gbk","UTF-8",等等))
2.1只读操作(r,rb)
1 #"E:\PyCharm\YJ\day8-2019-11-5\YJ呀.txt"(为要读取当前文件所在的路径/位置) 2 #mode ="r"(为只读模式) 3 #encoding ="UTF-8"(为字符集) 4 el = open("E:\PyCharm\YJ\day8-2019-11-5\YJ呀.txt",mode ="r",encoding ="UTF-8") 5 du = el.read() #read()(为阅读的意思) 6 print(du) 7 el.close() #close()为关闭文件,要养成良好的习惯打开了就要关闭
需要注意encoding表示编码集,根据文件的实际保存编码进行获取数据,对于我们而言,更多的是utf-8
2.2rb,读取出来的数据是bytes(字节)类型,在rb模式下,不能选择encoding字符集
1 el = open("E:\PyCharm\YJ\day8-2019-11-5\YJ呀.txt",mode ="rb") 2 du = el.read() #read()为读的意思 3 print(du) 4 el.close() #close()为关闭文件,要养成良好的习惯打开了就要关闭
结果为:b'Python\xe5\xad\xa6\xe5\xbe\x97\xe5\xa5\xbd\xe5\x9d\x90\xe7\x89\xa2\xe5\xba\xa7\xe5\xbe\x97\xe6\x97\xa9\r\nPython\xe5\xad\xa6\xe4\xb8\x8d\xe5\xa5\xbd\xe6\x90\xac\xe7\xa0\x96\xe6\x90\xac\xe5\x88\xb0\xe8\x80\x81\r\n\xe7\xaa\x97\xe5\xa2\x99\xe6\x98\x8e\xe6\x9c\x88\xe5\x85\x89\r\n\xe7\x96\x91\xe6\x98\xaf\xe5\x9c\xb0\xe4\xb8\x8a\xe9\x9c\x9c\r\n\xe4\xb8\xbe\xe5\xa4\xb4\xe6\x9c\x9b\xe6\x98\x8e\xe6\x9c\x88\r\n\xe4\xbd\x8e\xe5\xa4\xb4\xe6\x80\x9d\xe6\x95\x85\xe4\xb9\xa1\r\n\xe5\xad\xa6Python\xe5\xb0\xb1\xe6\x98\xaf\xe8\xa6\x81\xe5\x9d\x9a\xe6\x8c\x81\xef\xbc\x81\xef\xbc\x81\xef\xbc\x81\r\n'
rb的作用:在读取非文本文件的时候,比如MP3,图像,视频等信息的时候就需要用到rb,因为这种数据是没办法直接显示出来的在后面我们文件上传下载的时候还会用到,还有我们看的直播实质上就是这种数据经过编译后才能正常显示出来,这种一般人是看不懂的,只有机器能看懂!
绝对路径和相对路径:
1.绝对路径:从低往上翻意思就是,从磁盘根目录开始一直到需要的文件名
2. 相对路径:同一个文件夹下的文件相对于当前这个程序所在的文件夹而言如果在同一个文件夹中. 则相对路径就是这个文件名. 如果在上一层文件夹. 则要../
推荐使用相对路径:因为在我们把程序拷贝给别人使用的时候,直接把项目拷贝走就能运行,但是如果用绝对路径,哪还需要拷贝外部的文件
2.3读取文件的方法:
1.read()将文件中的内容全部读取出来,弊端:占内存如果文件过大容易导致内存崩溃
1 #"E:\PyCharm\YJ\day8-2019-11-5\YJ呀.txt"(为要读取当前文件所在的路径/位置) 2 #mode ="r"(为只读模式) 3 #encoding ="UTF-8"(为字符集) 4 el = open("E:\PyCharm\YJ\day8-2019-11-5\YJ呀.txt",mode ="r",encoding ="UTF-8") 5 du = el.read() #read(),为阅读的意思 6 print(du) 7 el.close() #close()为关闭的意思 8 结果为: 9 Python学得好坐牢座得早 10 Python学不好搬砖搬到老 11 窗墙明月光 12 疑是地上霜 13 举头望明月 14 低头思故乡 15 学Python就是要坚持!!!
2. read(n)读取n个字符
1 el = open("E:\PyCharm\YJ\day8-2019-11-5\YJ呀.txt",mode ="r",encoding ="UTF-8") 2 du = el.read(6) #结果显示为Python因为英文一个字符代表一个字母,要是换坐中文这里就会显示出连个中文!
3 print(du)
4 el.close()
5 结果为;
6 Python
需要注意的是,如果再次运行程序读取,那么会在当前位置继续去读而不是从头读!!!
1 el = open("E:\PyCharm\YJ\day8-2019-11-5\YJ呀.txt",mode ="r",encoding ="UTF-8") 2 du = el.read(6) 3 du1 = el.read(6) 4 du2 = el.read(6) 5 print(du) 6 print(du1) 7 print(du2) 8 el.close() 9 结果为; 10 Python 11 学得好坐牢座 12 得早 13 Pyt
如果使用rb模式,则读取出来的是n个字节
1 el = open("E:\PyCharm\YJ\day8-2019-11-5\YJ呀.txt",mode ="rb") 2 du = el.read(15) 3 print(du) 4 el.close() 5 结果为: 6 b'Python\xe5\xad\xa6\xe5\xbe\x97\xe5\xa5\xbd'
3.readline()一次读取一行数据,注意:readline()结尾,注意每次读取出来的数据都会有一个\n所以,需要我们使用strip()方法来去掉\n或者空格,
在readline()后面加.strip()即可。
1 el = open("E:\PyCharm\YJ\day8-2019-11-5\YJ呀.txt",mode ="r",encoding="UTF-8") 2 du = el.readline() #readline()为每次打印一行 3 du1 = el.readline() 4 du2 = el.readline() 5 du3 = el.readline() 6 print(du) 7 print(du1) 8 print(du2) 9 print(du3) 10 el.close() 11 结果: 12 13 Python学得好坐牢座得早 14 15 Python学不好搬砖搬到老 16 17 窗墙明月光 18 19 疑是地上霜
4.reanlines()将每一行形成一个元素,放到一个列表,将所有的内容读取出来,所以容易出现内存崩溃,不推荐使用
1 el = open("E:\PyCharm\YJ\day8-2019-11-5\YJ呀.txt",mode ="r",encoding="UTF-8") 2 du = el.readlines() #每一行形成一个元素, 放到一个列表中 3 print(du) 4 el.close() 5 for lie in du: 6 print(lie.strip()) #strip去空格等等 7 结果: 8 ['Python学得好坐牢座得早\n', 'Python学不好搬砖搬到老\n', '窗墙明月光\n', '疑是地上霜\n', '举头望明月\n', '低头思故乡\n', '学Python就是要坚持!!!\n'] 9 Python学得好坐牢座得早 10 Python学不好搬砖搬到老 11 窗墙明月光 12 疑是地上霜 13 举头望明月 14 低头思故乡 15 学Python就是要坚持!!!
5.循环读取,这种方式是组好的,每次读取一行内容,不会产生内存溢出问题
1 el = open("E:\PyCharm\YJ\day8-2019-11-5\YJ呀.txt",mode ="r",encoding="UTF-8") 2 for lie in el: 3 print(lie.strip()) 4 结果; 5 Python学得好坐牢座得早 6 Python学不好搬砖搬到老 7 窗墙明月光 8 疑是地上霜 9 举头望明月 10 低头思故乡 11 学Python就是要坚持!!!
注意:读取完的文件记得一定要关闭,要养成良好的习惯,el.close()
三,写模式(w, wb)
写读的时候注意:如果没有文件,则会自动创建文件,如果文件存在则会将原件中原来的内容清空,再写入新的内容
wb模式下,可以不指定打开文件的编码,但是再写文件的时候必须将字符串转换为utf-8的bytes(字节)数据
1 el = open("E:\PyCharm\YJ\day8-2019-11-5\YJ呀.txt",mode ="wb") 2 el.write("我是YJ呀!!!".encode("utf-8")) 3 el.flush() #刷新 4 el.close() #关闭 5 结果为: 6 我是YJ呀!!!因为写入之前会清空里面的内容
四,追加(a, ab)
在追加模式下,我们写入的内容会追加在文件的结尾
1 el = open("E:\PyCharm\YJ\day8-2019-11-5\YJ呀.txt",mode ="a",encoding = "utf-8") 2 el.write("要加油要坚持!!!") 3 el.flush() #刷新 4 el.close() #关闭 5 结果: 6 我是YJ呀!!!要加油要坚持!!!
五,读写模式(r+,r+b)
对于读写模式,必须是先读后写,因为默认光标实在开头的,准备读取的,读完后再进行写入,因为当读完后光标是在后面的,我们以后使用频率最高的模式是r+
注意注意一定一定要正常读完之后,再写入,否则开头的内容会改成你写入的内容覆盖掉
1 el = open("E:\PyCharm\YJ\day8-2019-11-5\YJ呀.txt",mode ="r+",encoding = "utf-8") 2 du = el.read() #先读 3 el.write("成功就在眼前!!!",encode("utf-8")) 4 print(du) 5 el.flush() #刷新 6 el.close() #关闭
六,写读(w+,w+b)
先将所有内容清空,然后写入,最后读取,但是读取的内容是空的,不常用
1 el = open("E:\PyCharm\YJ\day8-2019-11-5\YJ呀.txt",mode ="w+",encoding = "utf-8") 2 el.write("成功就在眼前!!!") 3 du = el.read() 4 print(du) 5 el.flush() #刷新 6 el.close() #关闭 7 输出结果什么也看不到因为写完光标在后面,读的时候开始光标在后面开始读后面没用内容所以读出来是空白的
七,追加读(a+)
a+模式下,不论先读还是后读,都是读取不到数据的
1 el = open("E:\PyCharm\YJ\day8-2019-11-5\YJ呀.txt",mode ="a+",encoding = "utf-8") 2 el.write("YJ加油!") 3 du = el.read() #阅读 4 print(du) 5 el.flush() #刷新 6 el.close() #关闭 7 结果:看不到,要打开文件才能看到最加的内容,追加的内容为(YJ加油!)
八. 常用的操作
1. 光标(seek),光标移动到n位置,注意,移动的单位是byte(字节),所以如果是UTF-8的中文部分要3的倍数,意思就是一个字要三个字节
移动到开头:seek(0)
移动到结尾:seek(0,2) ,seek的第二个参数表示的是从哪个位置进行偏移,默认是0,表示开头,1表示当前位置,2表示结尾
1 el = open("E:\PyCharm\YJ\day8-2019-11-5\YJ呀.txt",mode ="r+",encoding = "utf-8") 2 el.seek(0) #光标移动开头 3 du = el.read() #读取内容此时光标移动到结尾 4 print(du) 5 el.seek(0) #再次将光标移动到开头 6 el.seek(0,2) #将光标移动到结尾 7 du1 = el.read() #读取内容什么也没有读到因为此时光标在后面 8 print(du1) 9 10 el.seek(0) #光标移动到开头 11 el.write("哈哈哈") #写入信息,此时光标在9,因为中文3个字节代表一个字符3*3=9 12 el.flush() #刷新 13 el.close() #关闭 14 结果: 15 YJ加油!YJ加油!YJ加油!YJ加油!哈哈哈
2. tell() 使用tell()可以帮我们获取到当前光标在什么位置
1 el = open("E:\PyCharm\YJ\day8-2019-11-5\YJ呀.txt",mode ="r+",encoding = "utf-8") 2 el.seek(0) #光标移动开头 3 du = el.read() #读取内容此时光标移动到结尾 4 print(du) 5 el.seek(0) #再次将光标移动到开头 6 el.seek(0,2) #将光标移动到结尾 7 du1 = el.read() #读取内容什么也没有读到因为此时光标在后面 8 print(du1) 9 el.seek(0) #光标移动到开头 10 el.write("哈哈哈") #写入信息,此时光标在9,因为中文3个字节代表一个字符3*3=9 11 12 print(el.tell()) #此时获取光标所在的位置,中文一个字三个光标为一个字,因为中文3个字节代表一个字符 13 14 el.flush() #刷新 15 el.close() #关闭
3. truncate 截断文件
1 el = open("E:\PyCharm\YJ\day8-2019-11-5\YJ呀.txt",mode ="w",encoding = "utf-8") 2 el.write("哈哈") #写入两个字符 3 el.seek(3) #光标移动到3,就是两个字的中间 4 el.truncate() #删除光标后面的所有内容 5 el.close() #关闭 6 7 8 el = open("E:\PyCharm\YJ\day8-2019-11-5\YJ呀.txt",mode ="r+",encoding = "utf-8") 9 du = el.read(3) #读取12个字节,意思就是三个字 10 el.seek(4) 11 print(el.tell()) 12 el.truncate() #删掉后面的所有内容 13 el.flush() #刷新 14 el.close() #关闭
注意!!!:在r+模式下,如果读取内容,不论读取内容多少,光标显示的是多少,再次写入或者操作文件的的时候都是在结尾进行的操作,所以如果想做截取操作,记住了,先要挪动光标,挪动到你想要截取的位置,然后再进行截取关于truncate(n),如果给出了n,则从开头进行截取,如果不给n,则从当前位置截取,后面的内容将会被删除
九. 修改文件以及另一种打开文件的方式
文件修改,只能将文件中的内容读取到内存中,将信息修改完毕,然后将文件删除,将新文件的名字修改成老文件的名字
1. 引入os模块
2. 打开目标文件, r
3. 打开文件副本, w
4. 从r中读取内容进行修改. 写入到副本中
5. 删除源文件
6. 重命名副本
弊端:一次将文件所有内容进行读取,内存溢出,会导致机器崩溃,解决方案:写for循环一行一行的读取和操作
2019年11月6日