python 文件处理
5.1 文件的处理机制
打开
f=open('a.txt',mode='r',encoding='utf-8') #变量赋值
读/写
data=f.read()
print(data)
关闭
f.close() #回收操作系统的资源 del f #回收python资源,python回收机制自动处理,不用写 print(f)
流程分析:
1:向操作系统发起系统调用
2:操作系统打开这个文件,返回一个文件句柄给应用程序
3:在应用程序中把文件句柄赋值给一个变量
注意两点:
1:打开一个文件对应两部分,一个Python级别的文件句柄,另外一个是操作系统打开的文件(默认打开文件的编码是以操作系统的编码为准的,除非open()指定encoding='编码' )
2:当文件操作完毕后,应该回收两部分资源,
del f:回收应用程序资源(python解释器自动的垃圾回收机制已经替我们做了)
f.close:回收操作系统
上下文管理with 自动关闭系统的占用f.close()
with open('a.txt',mode='r',encoding='utf-8') as f: print(f.read())
5.2 文件打开的模式
5.2.1 读 r
读操作: r只读模式,默认是rt文本读
f=open('a.txt','r',encoding='utf-8') data1=f.read() print('=1===>',data1)
去掉读取一行后的换行符
print(f.readlines()) print(f.readline(),end='') #去掉读取一行后的换行符 f.close() #文件关闭,回收操作系统的资源
5.2.2 写 w
写操作:w只写模式,默认是wt文本写,如果文件不存在则创建,存在则清空+覆盖
f=open('a.txt','w',encoding='utf-8') f.write('11111\n') f.write('222222\n') f.write('1111\n2222\n3333\n') f.writelines(['哈哈哈哈\n','你好','alex']) f.close()
5.2.3 追加 a
追加:文件不存在则创建,文件存在那么在打开文件后立刻将光标移动到文件末尾,进行追加写
f=open(r'b.txt','a',encoding='utf-8') # print(f.writable()) #查看文件是否可写 f.write('4444\n') f.write('5555\n') f.writelines(['66666\n','7777\n']) f.close()
5.2.4 二进制读取 b(bytes)
#rb with open('111.png','rb') as f: print(f.read()) with open('b.txt','rb',) as f: print(f.read().decode('utf-8')) #rt with open('b.txt','rt',encoding='utf-8') as f: print(f.read()) #wb with open('b.txt','wb') as f:
res='中问'.encode('utf-8') print(res,type(res)) f.write(res) #ab with open('b.txt','ab') as f: res='哈哈哈'.encode('utf-8') print(res,type(res)) f.write(res)
5.3 操作文件的方法
#掌握 f.read() #读取所有内容,光标移动到文件末尾 f.readline() #读取一行内容,光标移动到第二行首部 f.readlines() #读取每一行内容,存放于列表中 f.write('1111\n222\n') #针对文本模式的写,需要自己写换行符 f.write('1111\n222\n'.encode('utf-8')) #针对b模式的写,需要自己写换行符 f.writelines(['333\n','444\n']) #文件模式 f.writelines([bytes('333\n',encoding='utf-8'),'444\n'.encode('utf-8')]) #b模式 #了解 f.readable() #文件是否可读 f.writable() #文件是否可读 f.closed #文件是否关闭 f.encoding #如果文件打开模式为b,则没有该属性 f.flush() #立刻将文件内容从内存刷到硬盘 f.name
5.4 文件的修改
将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,修改完毕后,再由内存覆盖到硬盘(word,vim,nodpad++等编辑器),不推荐使用,只适合小文件
import os with open('info.txt','r',encoding='utf-8') as read_f,open('.info.txt.swap','w',encoding='utf-8') as write_f: data=read_f.read() write_f.write(data.replace('alex','SB')) os.remove('info.txt') os.rename('.info.txt.swap','info.txt')
将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件
import os with open('info.txt', 'r', encoding='utf-8') as read_f, open('.info.txt.swap', 'w', encoding='utf-8') as write_f: for line in read_f: if 'SB' in line: line=line.replace('SB','alex') write_f.write(line) os.remove('info.txt') os.rename('.info.txt.swap', 'info.txt')
3. 了解部分
# "+" 表示可以同时读写某个文件 # r+, 读写【可读,可写】 # w+,写读【可读,可写】 # a+, 写读【可读,可写】 # x, 只写模式【不可读;不存在则创建,存在则报错】 # x+ ,写读【可读,可写】 # xb
5.5 文件的复制
#!/usr/bin/env python #1、源大小的问题: #2、文件打开模式的问题:b import sys _,src_file,dst_file=sys.argv with open(src_file,'rb') as read_f,open(dst_file,'wb') as write_f: # data=read_f.read() # write_f.write(data) #一次性读取和写入文件 for line in read_f: write_f.write(line) # write_f.flush() #立即写入硬盘,否则操作系统会接收一定长度时才写入磁硬盘
5.6 文件内光标的移动
f.tell:当前光标的的位置,以字节为单位
with open('a.txt','r',encoding='utf-8') as f: data1=f.read() print('==1==>',data1) print(f.tell()) data2=f.read() print('==2==>',data2)
read(3):
1. 文件打开方式为文本模式时,代表读取3个字符
2. 文件打开方式为b模式时,代表读取3个字节
#只有一种情况光标以字符为单位:文件以rt方式打开,read(3) with open('c.txt','rt',encoding='utf-8') as f: print(f.read(6)) print(f.tell()) f.seek(0,0) print(f.read(6))
seek():有三种移动方式0,1,2,其中1和2必须在b模式下进行,但无论哪种模式,都是以bytes为单位移动的
with open('c.txt','rb',) as f: f.seek(6,0) #以文件开头为基准 # f.seek(8,0) print(f.read()) with open('c.txt','rb') as f: print(f.read(6)) f.seek(2,1) #以鼠标当前位置为基准 print(f.tell()) print(f.read().decode('utf-8')) with open('c.txt','rb') as f: # f.seek(-3,2) #以文件末尾为基准 # print(f.tell()) f.seek(0,2)
Truncate():是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果
with open('access.log','a',encoding='utf-8') as f: f.truncate(3)
利用seek实现tail -f 功能
#tail -f access.log import time with open(r'C:\Users\Administrator\PycharmProjects\python20期\day3\access.log','rb') as f: f.seek(0,2) while True: line=f.readline() # print('===>',line) if line: print(line.decode(),end='') else: time.sleep(0.05)