十五、python文件IO操作

十五、python文件IO操作

python文件操作的步骤

python文件的操作就三个步骤:
1. 先open打开一个要操作的文件
2. 操作此文件(读,写,追加等)
3. close关闭此文件

python文件访问模式

简单格式: file_object = open(file_path,mode=" ")

mode:
r 只读模式,不能写(文件必须存在,不存在会报错)
w 只写模式,不能读(文件存在则会被覆盖内容(要千万注意),文件不存在则创建)
a 追加模式,不能读
r+ 读写模式
w+ 写读模式
a+ 追加读模式
rb 二进制读模式
wb 二进制写模式
ab 二进制追加模式
rb+ 二进制读写模式
wb+ 二进制写读模式
ab+ 二进制追加读模式

只读模式(r)

# 先操作系统head -5 /etc/passwd > /tmp/1.txt准备一个文件
f=open("/tmp/1.txt",encoding="utf-8") # 默认就是只读模式
# 刚打开一个文件(就是一个内存对象或者叫文件句柄要赋值给一个变量,通过变量进行后续操作);如果不同平台,可能会字符集编码不一致,不一致的需要指定;一致的不用指定。
data1=f.read()
data2=f.read() # 读第二遍
f.close()
print(data1)
print("="*50)
print(data2) # 发现读第二遍没有结果;类似从上往下读了一遍,第二次读从最后开始了,所以就没结果了

只写模式(w)

f=open("/tmp/1.txt",'w')  # 只写模式(不能读),文件不存在则创建新文件,如果文件存在,则会复盖原内容(千万要小心)
data=f.read() # 只写模式,读会报错
f.close()

# 创建新文件,并写入内容
f=open("/tmp/2.txt",'w') # 文件不存在,会帮你创建(类似shell里的 > 符号)
f.write("hello\n") # 不加\n,默认不换行写
f.write("world\n")
f.truncate() # 截断,括号里没有数字,那么就是不删除
f.truncate(3) # 截断,数字为3,就是保留前3个字节
f.truncate(0) # 截断,数字为0,就是全删除
f.flush() # 相当于把写到内存的内容刷新到磁盘(要等到写的数据到缓冲区一定量时才会自动写,用此命令就可以手动要求他写)
f.close()

#针对flush的扩展
import sys,time
for i in range(50):
	sys.stdout.write("=") # print打印会自动换行,这个可以不换行打印;或者print("=",end="")
	sys.stdout.flush() # 这一句不加的话,测试结果会发现不会每隔0.2秒打印,而是缓存了一定后,一次打印出来,加了这个flush就能看到是每隔0.2秒打印的效果了
	time.sleep(0.2)

追加模式(a)

f=open("/tmp/2.txt",'a') # 类似shell里的>>符
f.write("hello\n")
f.write("world\n")
f.truncate(0)
f.close()

扩展:
1.python里的a模式,是可以使用truncate方法来清空内容的
2.在linux系统里执行了下面命令后,则就只能追加此文件,而不能清空此文件内容
# chattr +a /tmp/2.txt
3.如果在linux系统里做了chattr +a /tmp/2.txt后,在python里再用w或a模式open此文件,就不可以使用truncate方法来清空内容了(因为python允许你这么做,但linux系统拒绝了)

深入理解 python的io操作

f=open("/tmp/2.txt","r")
print(f.tell()) # 告诉你光标在哪,刚打开文件,光标在0位置
f.seek(5) # 移你的光标到整个文件的第5个字符那
print(f.tell())
data1=f.read() # read是读整个文件在光标后面的所有字符(包括光标所在的那个字符),读完后,会
把光标移到你读完的位置
data2=f.readline() # readline是读光标所在这一行的在光标后面的所有字符(包括光标所在的那个字
符),读完后,会把光标移到你读完的位置
data3=f.readlines() # readlines和read类似,但把读的字符按行来区分做成了列表
f.close()
print("data1:",data1)
print("data2:",data2)
print("data3:",data3)

文件读的循环方法

f=open("/tmp/2.txt","r")
#循环方法一:
for index,line in enumerate(f.readlines()):
	print(index,line.strip()) # 需要strip处理,否则会有换行
# 循环方法二:这样效率较高,相当于是一行一行的读,而不是一次性全读(如果文件很大,那么一次性全读会速度很慢)
for index,line in enumerate(f):
	print(index,line.strip())
f.close()

通过/proc/meminfo得到可用内存的值

f=open("/proc/meminfo","r")
for line in f:
    if line.startswith("MemAvailable"):
		print(line.split()[1])
f.close()

通过/proc/cpuinfo得到cpu核数

f=open("/proc/cpuinfo","r")
count=0
for line in f:
	if line.startswith("processor"):
		count+=1
f.close()
print(count)

比较r+,w+,a+三种模式

r+不会改变原文件的数据,相当于在只读模式的基础上加了写权限;
w+会清空原文件的数据,相当于在只写模式的基础上加了读权限;
a+不会改变原文件的数据,相当于在只追加模式的基础上加了读权限;

r+,w+,a+混合读写深入理解

f=open("/tmp/2.txt","w+")
f.write("11111\n")
f.write("22222\n")
f.write("33333\n")
print(f.tell()) # 打印结果为18,表示光标在文件最后
f.write("aaa") # 这样写aaa,相当于在文件最后追加了aaa三个字符
f.seek(0) # 表示把光标移到0(也就是第1个字符)
f.write("bbb") # f.seek(0)之后再写bbb,就是把第一行前3个字符替换成了bbb
f.seek(0) # 把光标再次移到0
f.readline() # 把光标移到第1行最后
f.seek(f.tell()) # f.seek到第1行最后(如果这里理解为两个光标的话,你可以看作是把写光标同步到
读光标的位置)
f.write("ccc") # 这样写ccc,就会把第二行的前3个字符替换成ccc
f.close()

总结

r+,w+,a+这三种模式因为涉及到读与写两个操作,你可以使用两个光标来理解,但这样的话读光标与写光标会容易混
乱,所以我们总结下面几条:
1. f.seek(0)是将读写光标都移到第1个字符的位置
2. 如果做了f.read()操作,甚至是做了f.readline()操作,写光标都会跑到最后
3. 如果做了f.write()操作,也会影响读光标

所以建议在做读写切换时使用类似f.seek(0)和类似f.seek(f.tell())这种来确认一下位置,再做切换操作

posted @ 2023-06-21 11:36  村尚chun叔  阅读(18)  评论(0编辑  收藏  举报