文件处理
文件处理
文件处理
我们在操作文件的时候其实操作的是硬盘,文件其实是操作系统暴漏给我们可以简单快捷的操作硬盘的接口
绝对路径:
非常详细的路径,无论什么人都可以找到
相对路径:
有一个参考,只有对应的人才可以找到
with open(文件路径, mode = 模式, encoding = 'utf-8') as f:
f.read()
'''
with子代码块运行结束之后会调用close关闭文件资源
中国所有的windows电脑内部默认的编码;是gbk
'''
在写文件路径之前最好加一个r 取消转义,,因为在python中 '\' 这个字符用的很多
res = r'E:\pythonDemo\python老男孩培训\文件处理'
文件的打开模式
# 文件的打开模式
'''
r: (默认)只读模式,文件不存在则会报错,文件存在则文件指针处于文件开头
w: 只写模式,文件不存在则会创建新文件,文件存在则清空,指针处于开头
a: 追加写模式,文件不存在则新建,文件存在不会清空,文件指针处于文件末尾
'''
# 控制文件读写内容的模式
'''
t:(默认),读写以字符串为单位,只用于文本文件,必须指定encoding参数
b: 读写以字节为单位,用于所有文件,不用指定encoding
'''
# rt模式
with open('a.txt', mode='rt', encoding='utf-8')as f:
print(f.read())
print(f.readable())
print(f.writable())
=======>
qwe
仰天大笑出门去
我辈岂是蓬蒿人
True
False
# wt模式
with open('a.txt',mode='wt', encoding='utf-8')as f:
f.write('己所不欲勿施于人')
print(f.writable()) # 判断可不可以写
print(f.readable()) # 判断可不可以读
====>
True
False
'''
以w模式打开,先清空整个文件夹,在往里面写东西,如果**文件没有关闭**则在尾部写,若文件关闭,则重新打开就会先清空
'''
# at模式
with open('a.txt', mode='at', encoding='utf-8')as f:
f.write('仰天大笑出门前\n我辈岂是蓬蒿人')
'''
文件指针一直处于文件末尾
打开了文件没有关闭的情况下,新写的内容一直跟在原先的内容后面,这一点与w模式相同,
若打开了文件关闭又重新打开,则继续在原先内容末尾写,这点与w相反
'''
# b模式
with open('1.jpg', mode='rb')as f:
print(f.read())
'''
这个模式下得到的是一个bytes类型,不是所有的bytes都可以解码,解码要先知道怎么编码,
可以适用于所有文件
'''
例
实现文件拷贝功能(包括图片视频,所以用b模式)
with open('1.jpg', mode='rb') as f, \
open('2.jpg', mode='wb')as f1:
f1.write(f.read())
'''
这个文件的拷贝虽然实现了,但是如果这个文件很大呢,要是这个文件很大,从硬盘读一次性过来,你电脑内存就爆了
'''
# 优化版
with open('1.jpg',mode='rb')as f, \
open('3.jpg', mode='wb') as f1:
for i in f:
f1.write(i)
文件打开的混合方式
'''
r+t : 既可以读又可以写,倾向于r模式
w+t :可读可写,倾向于w模式,如果又要读又要写,则文件打开会先清空,再写
a+t : 可读可写
r+b:可读可写
w+b:可读可写
a+b:可读可写
'''
文件操作的其他方法
with open('a.txt', mode='rt', encoding='utf-8')as f:
# print(f.readline())
print(f.readlines()) # ===> ['己所不欲勿施于人仰天大笑出门前\n', '我辈岂是蓬蒿人']
'''
readline(): 文件只读一行,
readlines(): 文件一行一行读,放在一个列表中,可以用for循环的方式实现,
for i in f:
lines[].append(i)
print(lines)
'''
with open('a.txt', mode='wt', encoding='utf-8')as f:
lines = ['qwert\n', 'asdfg\n', 'zxcvb\n']
f.writelines(lines)
'''
writelines: 把要写的内容放在一个列表中,直接把这个列表传给writelines()
这个方法等同于for 循环
lines = ['qwert\n', 'asdfg\n', 'zxcvb\n']
for i in lines:
f.write(i)
'''
flush()
'''
这个可以尽快的写到硬盘里面去,不过效率降低了
'''
控制文件指针的移动
只有t模式下的read(n),n以字符为单位,其他都是以字节为单位
一个英文字符占一个字节,一个中文字符三个字节
文本文件中,没有使用b模式选项打开的文件,只允许从文件头开始计算相对位置
# 第一种: f.read()
with open('a.txt',mode='rt',encoding='utf-8') as f:
res = f.read(6)
print(res)
with open('a.txt',mode='rb') as f:
# res = f.read(6)
res = f.read(8)
print(res.decode('utf-8'))
'''
其实就是,read读模式打开,文件指针在开头,括号里面跟几就是从左往右读取几个字节,t模式下字符为单位,其他均为字节
'''
# 第二种 f.truncate()--截取
with open('a.txt',mode='at',encoding='utf-8') as f:
f.truncate(8)
'''
截取,顾名思义,不能是r模式,不能是w模式(打开会直接清空),a模式或是r+t模式也行
打开文件,指针从文件开头截取到<truncate(n)>第n个字节保留,其他全部清空
'''
# 第三种 f.seek
'''
f.seek(字节个数,0) ---指针在文件开头
f.seek(字节个数,1) ---指针在文件当前位置
f.seek(字节个数,2) ---指针在文件末尾
'''
列:
---a.txt----
qwertasd己所不欲勿施于人
# f.seek(字节个数,0) ---指针在文件开头
with open('a.txt',mode='rt', encoding='utf-8')as f:
f.seek(3, 0) # 文件从开头向右移动三个字节
print(f.tell()) # 打印文件移动了几个字节
print(f.read()) # 从文件第三个字节处,往右读
====>
3
rtasd己所不欲勿施于人
# f.seek(字节个数,1) ---指针在文件当前位置
with open('a.txt', mode='rb') as f:
f.seek(3, 1)
print(f.tell())
f.seek(5, 1)
print(f.tell())
print(f.read())
====>
3
8
己所不欲勿施于人
# f.seek(字节个数,2) ---指针在文件末尾
with open('a.txt', mode='rb') as f:
f.seek(0,2) # 文件2模式,第0个位置开始,直接跳到文件末尾
print(f.tell())
f.seek(-3,2) # 从文件末尾往左移动三个字节
print(f.tell())
print(f.read().decode('utf-8'))
====>
32
29
人
文件修改的两种方式
# 方案一:
----------a.txt-----------
qwertasd己所不欲勿施于人
-----------py------------
with open('a.txt', mode='rt', encoding='utf-8')as f:
data = f.read()
with open('a.txt', mode='wt', encoding='utf-8')as f:
f.write(data.replace('QWERTASD', 'QWERTASD'.lower()))
# 方案二:
import os
with open('a.txt', mode='rt', encoding='utf-8')as f, \
open('.a.txt.swap', mode='wt',encoding='utf-8')as f1:
for line in f:
f1.write(line.replace('qwertasd', 'qwertasd'.upper()))
os.remove('a.txt')
os.rename('.a.txt.swap', 'a.txt')
'''
方案一: 现在用到的文本编辑器都是用这种方式处理,如果文件很大,一次性打开会耗费大量内存,所以要内存要预留出足够的空间,不过为了客户体验,,现在的文本编辑器依旧用这种办法。
方案二: 不耗费内存也不耗费硬盘。
'''
实现一个小小的需求,可以动态检测到日志的更新并打印
------------记录日志---------------
import time
with open('accescc.log', mode='at', encoding='=utf-8')as f:
f.write(f'{time.strftime("%Y-%m-%d %H:%M:%S")}记录了一条日志\n')
---------检测日志并打印-------------
with open('accescc.log', mode='rb')as f:
f.seek(0,2)
while True:
line = f.readline()
if len(line) == 0:
continue
else:
print(line.decode('utf-8'), end = '')
浙公网安备 33010602011771号