Python 文件相关操作

本文详细介绍了Python中的文件操作,包括不同模式(如只读、写入、追加等)的使用,以及read、write、append、seek、tell、truncate等方法。强调了在读写模式下操作文件的注意事项,特别是r+模式下必须先读后写,以及截断文件和修改文件内容的方法。
摘要由CSDN通过智能技术生成
初识文件系统:

使用Python 来读写文件是非常简单的操作,我们使用open()函数来打开一个文件,获取到文件句柄,然后通过文件的句柄就可以进行各种各样的操作了,根据打开的不同方式的不同能够执行的操作也会有相应的差异.

打开文件的方式: r (只读) , w(只写) , a(追加) , r+(读写) , w+(写读) , a+(追加写读) , rb , wb , ab , r+b , w+b , a+b . 默认使用的是r(只读)模式

只读操作(r, rb):
	f = open("drift.txt", mode="r", encoding="UTF-8")
	s = f.read()
	print(s)
	f.close() # 如果没有这句话, 你在下面的程序中如果删除这个文件. 就会报错

需注意encoding表示编码集,根据文件的实际保存编码进行获取数据,对我们而言,更多的是utf-8.

rb .读取出来的数据时bytes类型,在rb模式下,不能选择encoding字符集.

	f = open("drift.txt",mode="rb")
	content  = f.read()
	print(content)
	f.close()

注意 : rb 的作用在读非文本文件的时候,比如读取MP3 , 图像,视频等信息的时候就需要用到rb,因为这种数据是没有直接显示出来的,在后面我们上传下载的时候换回用到还有我们看的直播,实际上都是这种数据.

绝对路径和相对路径:

绝对路径: 从磁盘根目录开始一直到文件名.
相对路径:同一文件夹下的文件,相对于当前这个进程所在的文件夹而言,如果在同一文件中,则相对路径就是这个文件名, 如果在上上一层文件夹,则为 ../ 上上层 ../../  一次类推.

这里推荐大家写代码时使用相对路径,因为我们把程序拷给别人使用的时候,直接将项目拷贝走就可以运行,但是如果用绝对路径,那就还需要拷贝外部的文件. (像输出的确定文件的路径推荐使用绝对路径).

读取文件的方法:

测试文件:

 江湖人称漂少
 一生中的最爱

1 . read()将文件中的内容全部读取出来,弊端:占内存,如果文件过大,容易导致内存崩溃

	f = open("../drift.txt",mode="r",encoding="utf-8")
	s = f.read()
	print(s)
	f.close()

结果:
在这里插入图片描述
2 . read(n)读取N个字符,需注意的是.如果再次读取,那么会在当前位置继续去读而不是从头读,如果使用的是 rb 模式,则读取出口的是 n 个字节

	f = open("../drift.txt", mode="r", encoding="utf-8")  # mode 为r 
	s = f.read(3)         
	print(s)
	f.close()

结果:
在这里插入图片描述

	f = open("drift", mode="rb")   # mode 为 rb
	s = f.read(3)
	print(s)
	f.close()

结果:
在这里插入图片描述
3 . readline() 一次读取一行的数据,注意:readline()结尾,每次读取出来的数据都会有一个\n 所以呢,需要我们使用strip()方法来去掉\n或者空格

	f = open("../drift.txt", mode="r", encoding="utf-8")
	s = f.readline()
	s1 = f.readline()
	s2 = f.readline()
	print(s)
	print(s1)
	print(s2)
	f.close()

结果:
在这里插入图片描述
4. readlines() 将每一行形成一个元素,放到一个列表中,将所有的内容都读取出来,文件过大容易出现内存崩溃的问题,不推荐使用.

	f = open("drift", mode="r", encoding="utf-8")
	lst = f.readlines()
	for line in lst :
	    print(line.strip())
	f.close()

结果:
在这里插入图片描述
5. 循环读取: 这种方式是最好的,每次读取一行内容,不会产生内存溢出的问题,推荐使用.

	f = open("../drift.txt", mode="r", encoding="utf-8")
	for line in f :
	    print(line.strip())
	f.close()

在这里插入图片描述

写模式(w , wb)

写文件的时候注意,如果没有文件,则会创建,如果文件存在,则会将原文件的内容删除,再写入新的内容

	f = open("drift", mode="w", encoding="utf-8")
	f.write("你是谁")
	f.flush()     # 刷新,每次写完文件切记刷新,良好的习惯.
	f.close()

尝试读一读刚才写入的文件

	f = open("drift", mode="r", encoding="utf-8")
	s = f.read()
	print(s)
	f.close()

结果如下:
在这里插入图片描述
wb 模式下.可以不指定打开文件的编码,但是在写文件的时间必须捋字符串转化成为utf-8的bytes数据.如下:

	f = open("drift", mode="wb")
	f.write("你是谁,我在那".encode("utf-8"))
	f.flush()
	f.close()

结果如下 :
在这里插入图片描述

追加(a,ab)

在追加模式,我们写入的内容会追加在文件的结尾(会在光标的后面添加) . 如下 :

	f = open("drift", mode ="a",encoding="utf-8")
	f.write("我是你的什么,请你回答我")
	f.flush()
	f.close()

结果:
在这里插入图片描述
ab 模式:

	f = open("drift", mode="ab")
	f.write("你问我我是谁我在哪".encode("utf-8"))
	f.flush()
	f.close()

结果 :
在这里插入图片描述

读写模式(r+ ,r+b):

对于读写模式,必须是先读,因为默认光标是在开头的,准备读取的,当读完了之后在进行写入,我们以后使用的频率最高的模式就是r+
正确的操作:

f = open("drift", mode="r+",encoding="utf-8")
	s = f.read()
	f.write("你是谁的谁,我是我的我")
	print(s)
	f.flush()
	f.close()

运行结果:
在这里插入图片描述
drift 文件中:
在这里插入图片描述
错误的操作:

	f = open("drift", mode="r+",encoding="utf-8")
	f.write("你是谁的谁,我是我的我")
	s = f.read()
	print(s)
	f.flush()
	f.close()

运行结果:
在这里插入图片描述
drift 文件中:
在这里插入图片描述
** 将开头的内容写成了"你是谁的谁,我是我的我" 然后读取的数据才是文件中的内容
所以记住: 在r+ 模式中,必须是先读取,然后再写入

写读(w+.w+b)

先讲所有的内容先清空,然后再写入,最后读取,但是读取的内容是空的,不常用

f = open("drift",mode="w+",encoding="utf-8")
f.write("难搞哦")
s = f.read()
print(s)
f.flush()
f.close()

结果如下 :
在这里插入图片描述
有人会说,先读不就好了么,错,W+模式下,一开始读取不到数据,然后写的时候再捋原来的内容清空,所以,很少用.

追加读(a+):

a+ 模式下,不论先读还是后读,都是读取不到数据的.

	f = open("drift",mode="w+",encoding="utf-8")
	f.write("难搞哦")
	s = f.read()
	print(s)
	f.flush()
	f.close()

还有一些其他的带b 的操作,就不再多描述了哈,就是把字符换成字节,仅此而已

其他相关操作
seek

seek(n)光标移动到n位置,注意,移动的单位是byte,所以如果不是utf-8的中文部分要是 3 的倍数
通常我们使用seek()都是来移动到开头或者结尾

移动到开头 : seek(0)
移动到当前光标所在位置: seek(0,1)
移动到结尾: seek(0,2) 

seek 的第二个参数表示的是从哪个位置进行偏移,默认是0 , 表示开头,1 表示当前位置, 2表示结尾.

	f = open("drift",mode="r+",encoding="utf-8")
	f.seek(0)     # 移动光标到开头
	s = f.read()     # 读取内容
	print("内容是",s)
	f.seek(0)        # 再次将光标移动到开头
	f.seek(0,2)      # 将光标移动到结尾
	s1 = f.read()    # 读取内容
	print("内容是",s1)
	
	
	f.seek(3)    # 移动光标 到第一个字符后,
	f.write("那是一个冬天 ,没有你的存在的身影")  #会将后面的删除掉
	f.seek(0)
	s2 = f.read()
	print("内容是",s2)
	f.close()

结果如下:
在这里插入图片描述

tell()

使用tell()可以帮助我们获取到当前光标在什么位置

	f = open("drift",mode="r+",encoding="utf-8")
	f.seek(0)   # 光标在开头
	s = f.read()   # 读取内容,此时移动到结尾
	print("内容是:",s)
	f.seek(0)      # 在次将光标移动到开头
	f.seek(0,2)    # 将光标移动到结尾
	s1 = f.read()  # 读取内容, 什么都没有为空
	print("内容是:",s1)
	
	f.seek(0)      # 移动到开头
	f.write("我是谁,我在哪")   # 写入信息
	print(f.tell())          # 当前光标所在位置
	f.flush()
	f.seek(0)				# 再次移动到开头
	s2 = f.read()
	print(s2)
	f.close()

结果如下:
在这里插入图片描述

truncate() 截断文件
	with  open("drift",mode="w",encoding="utf-8") as f :
	    f.write("每天都是一个新的开始")   # 写入字符
	    f.seek(3)        # 光标移动到3 也就是第一个字符后,
	    f.truncate()     # 删除光标后面的所有内容
	print(open("drift",mode="r",encoding="utf-8").read())  # 读取删除之后的文件

结果 :
在这里插入图片描述
定义函数的表达:

	def read_text(filename, text):
	    with  open(filename, mode="w", encoding="utf-8") as f:
	        f.write(text)  # 写入字符
	        f.seek(3)  # 光标移动到3 也就是第一个字符后,
	        f.truncate()  # 删除光标后面的所有内容
	    return open(filename, mode="r", encoding="utf-8").read()
	a = read_text(filename='drift.txt', text='每天都是一个新的开始')

结果同上

with  open("drift",mode="r+",encoding="utf-8") as f :
	    s = f.read()     # 读取当前文件内容
	    print(s)         
	    f.seek(3)        # 光标移动到3 也就是第一个字符后,
	    f.truncate()     # 删除光标后面的所有内容
	print(open("drift",mode="r+",encoding="utf-8").read())  # 读取删除之后的文件内容

结果显示 :
在这里插入图片描述
注意 : 深坑请注意,在 r+ 模式下,如果读取了内容,不论读取内容多少,光标显示的是多少,再写入或者操作文件的时候都是在结尾进行的操作.
所以 ,如果想做截断操作,记住了,要先挪动光标到你想要截取的位置,然后再进行截断关于truncate(n),如何给出了n, 则从开头进行截断,如果不给n,则从当前位置截取,后面的内容都会别删除

修改文件内容以及另一种打开文件的方式

文件修改,只能将文件的内容读取到内存中,将信息修改完毕,然后将源文件删除,将新的文件的名字改为老文件的名字.

	import os
	with open("drift",mode="r",encoding="utf-8") as f1, \
	    open("drift_new",mode="w",encoding="utf-8") as f2:
	    s = f1.read()
	    new_s = s.replace("每一天都是新的开始","谁是谁的谁")      # 修改的内容
	    f2.write(new_s)
	os.remove("drift")                         # 删除源文件
	os.rename("drift_new","drift")             # 重新命名

运行以上代码就会把原文件内容"每一天都是新的开始" 替换成为 “谁是谁的谁”
弊端 : 一次将所有的内容进行读取,内存溢出,解决方案: 一行行的进行读取和替换.
就需要引入 os 模块来实现

	import os
	with open("drift",mode="r",encoding="utf-8") as f1, \
	    open("drift_new",mode="w",encoding="utf-8") as f2:
	    for line in f1:
	        new_line = line.replace("我喜欢明天的明天","谁是谁的谁")    # 替换文件中的内容
	        f2.write(new_line)                                      # 写入新的内容
	os.remove("drift")                         # 删除源文件
	os.rename("drift_new","drift")             # 重新命名

运行以上代码,就会一行行找出来需要替换的内容后,再来操作修改.推荐使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值