文件操作
文件操作
- 什么是文件
操作系统提供给用户操作复杂硬件(硬盘)的简易接口。
- 为什么要操作文件
人或者程序需要永久的保存数据
- 如何操作操作文件
# 打开文件,得到文件句柄并赋值给一个变量
f = open('a.txt','r',encoding='utf-8')
# 通过句柄对文件进行操作
data = f.read()
# 关闭文件
f.close()
- 文件的两种格式(默认的文本模式为 rt)
1:t 模式为文本模式(text)
2:b 模式为二进制模式(bytes)
文件上下文操作
- with
with open('a.txt','r',encoding='utf-8')as fr:
print(fr)
# <_io.TextIOWrapper name='a.txt' mode='r' encoding='utf-8'>
文件的操作方法
#掌握
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
文件打开的模式
r 只读模式,w 只写模式,a 追加模式
# r 只读模式
with open('a.txt','r',encoding='utf-8')as fr: #默认打开文件为 'rt'
print(fr.readable()) # 是否可读 True
print(fr.writable()) # 是否可写 False
print(fr.read)
# 1.当文件不存在时,报错
# 2.read 一次性将文件的内容全部读出,光标移至文件末尾
print(fr.read)
# read 由于光标移至文件末尾,所以打印出一片空白
# w 只写模式
with open('a.txt','w',encoding='utf-8')as fw:
print(fw.readable()) # 是否可读 False
print(fw.writable()) # 是否可写 True
print(fw.write('content'))
# 1.文件不存在时,自动在同级目录下创建该文件
# 2.文件存在时,清空内容再写入 content
# a 追加模式
with open('a.txt','w',encoding='utf-8')as fa:
print(fa.readable()) # 是否可读 False
print(fa.writable()) # 是否可写 True
print(fa.write('content'))
# 1.当文件不存在的情况下,自动创建该文件
# 2.当文件存在的情况下,不清空文件内容, 文件的光标会移动文件的最后
可读,可写
- r + t:可读,可写
- w + t :可读,可写
- a + t:可追加,可读
# r + t
with open('text.txt','r+t',encoding='utf-8')as fr:
print(fr.readable()) # True
print(fr.writable()) # True
# 当文件不存在时报错
# w + t
with open('text.txt','w+t',encoding='utf-8')as fw:
print(fw.readable()) # True
print(fw.writable()) # True
# 当文件不存在时,新建
# a + t
with open('text.txt','w+t',encoding='utf-8')as fw:
print(fw.readable()) # True
print(fw.writable()) # True
# 当文件不存在时,新建
文件内指针的移动
假如用读写 r + t 去控制指针的移动。
# 文件内容:
# word,hello
# hello,word
# word,hello
with open('www','r+t',encoding='utf-8')as fr:
fr.readline() # 先将指针移至第一行的末尾。
fr.write('json 真衰呀')
# word,hello
# hello,word
# word,hellojson 真衰呀
# 直接在文件的最末尾添加
w + t:只是多了个可读的功能,些的话依然会清空文件内容后再将新的内容写入。
a + t:再文件末尾添加内容。
seek(offset,whence):
offset代表文件指针的偏移量(单位字节),whence代表指针的起始位置
- 方法:0,1,2:
只有 0 可以在 t 的模式下使用
1,2 只能在 b 的模式下使用:1代表的是当前位置,2代表的是文件末尾
- read() 括号里面可以加参数,代表可以读多少个字符,中文一般都表示三个字符
# seek
### read(n)
with open('text.txt','rt',encoding='utf-8')as fr:
res = fr.read(3)
print(res) # hel
### 1: 0代表的是指针在文件开头的位置
with open('text.txt','rt',encoding='utf-8')as fr:
fr.seek(10,0)
# tell() 统计从文件开头到当前指针的所在位置。
print(fr.tell()) # 10
### 2: 1代表指针所在的当前位置
with open('text.txt','rb')as fr:
fr.readline() # 读取文件的第一行后,光标在第一行的最末尾
print(fr.tell()) # 12
# 第一行文件的最末尾 \n 也算做两个字节
fr.seek(10, 1)
print(fr.tell()) # 22
### 3: 2代表的是指针在文件的末尾
with open('text.txt','rb')as fr:
fr.seek(-4, 2)
print(fr.tell()) # 30
# 基于seek实现 tail-f 功能
import time
times = time.strftime('%Y-%m-%d %X')
with open('text.txt','rb')as fr:
fr.seek(0,2)
while True:
line = fr.readline()
if line:
print(f'{times}{line.decode("utf-8")}')
文件的修改
文件的数据是存放于硬盘上的,因而只存在覆盖、不存在修改这么一说,我们平时看到的修改文件,都是模拟出来的效果,具体的说有两种实现方式:
方式一:将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,修改完毕后,再由内存覆盖到硬盘。
with open('file','r',encoding='utf-8')as fr:
res = fr.read()
with open('file','w',encoding='utf-8')as fw:
data = res.replace('word','jin')
fw.write(data)
方式二:将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件。
import os
with open('file','r',encoding='utf-8')as fr,\
open('file.swap','w',encoding='utf-8')as fw:
for line in fr:
res = line.replace('jin','word')
fw.write(res)
os.remove('file')
os.rename('file.swap','file')
千里之行,始于足下。