13.0、说明:
1、文件处理的步骤:
(1)打开文件时需要指定文件路劲和以何种方式打开文件,打开后即可获取该文件
句柄;
(2)通过句柄对文件进行操作;
(3)关闭文件;
(4)注意:
1)文件处理的数据内容全部为字符串类型,如果是其它数据类型会报错;
2)对文件的处理以光标所在的位置为起点,启动程序时光标默认从头开始;
3)对文件的修改操作实质是将文件读取(r操作)到内存中,在内存中进行修改,然后再覆盖(w操作)原文件或创建新的文件;
2、打开文件的模式:
(1)r:只读模式,默认模式,文件必须存在,不存在则抛出异常;
(2)w:只写模式,不可读,不存在则创建,存在则清空(类似于linux中写入重定向'>');
(3)x:只写模式,不可读,不存在则创建,存在则报错;
(4)a:追加模式,不可读,不存在则创建,存在则只追加内容(类似于Linux中的追加重定向'>>');
(5)注意:默认处理的文本模式(t),比如(rt),如果处理视频图片等其它格式的内容使用"b"来操作;
3、"+"表示可以同时读写某个文件:
说明:该模式是在原有打开文件模式上新增读或写功能
(1)r+:读写,可读,可写;
(2)w+:写读,可读,可写;
(3)x+:写读,可读,可写;
(4)a+:写读,可读,可写;
4、"b"表示以字节的方式操作:
注意:b模式打开文件时不能指定编码,但也要保证编码和解码的一致性
(1)rb 或 r+b;
(2)wb 或 w+b;
(3)xb 或 x+b;
(4)ab 或 a+b;
13.1、文件处理读操作(r):
只能读,文件不存在会报错;
1、读取全部内容:
f=open('告白气球',encoding='utf-8')
# 打开文件句柄,编码要和文件存储的编码一致,如果不写编码格式,默认会调取操作系统的编码;
print(f.encoding)
# 表示当前读取的文件是用什么编码格式进行解码
print(f.readable())
# 判断文件是否为可读,可读返回True,不可读返回False;
data=f.read()
# 读取文件的所有内容
print(data)
f.close()
# 关闭文件句柄
print(f.closed)
# 判断打开的文件句柄是否已经关闭,True表示已经关闭,false表示没有关闭
print(f.name)
# 打印打开文件的文件名
2、按行读取:
f=open('告白气球',encoding='utf-8')
print('第1行',f.readline())
print('第2行',f.readline(),end='')
# 按行读取,默认读取后会加换行符( ),"end=''"表示取消换行符,读取一行,
# 光标往下移动一行;
print('第3行',f.readline(),end='')
f.close()
3、将文件的每行以当作列表每个元素的方式进行输出:
f=open('告白气球',encoding='utf-8')
data=f.readlines()
print(data)
f.close()
#输出格式:
['塞纳河畔 左岸的咖啡 ', '我手一杯 品尝你的美 ', '留下唇印 的嘴']
13.2、文件处理写操作(w):
只能写,文件存不存在都会新建文件;
1、向文件中写入数据:
f=open('告白气球','w',encoding='utf-8')
f.writable()
# 判断文件是否可写
f.write('111 ')
f.write('222 ')
f.write('333 4444 555 ')
# 向文件中写入内容
f.close()
2、以列表的形式往文件中写入数据:
f=open('告白气球','w',encoding='utf-8')
f.writelines(['111 ','222 '])
f.close()
13.3、文件处理追加操作(a):
文件不存在时创建新的文件,文件存在时往文件中追加
1、追加操作:
f=open('告白气球','a',encoding='utf-8')
f.write('写到最后一行 ')
f.close()
13.4、文件处理修改文件操作:
对文件的修改操作实质是将文件读取(r操作)到内存中,在内存中进行修改,然后再覆盖(w操作)原文件或创建新的文件;
1、覆盖操作:
f=open('告白气球','r+',encoding='utf-8')
print(f.readable())
f.write('哈哈')
# 文件第一行的前两个字会被覆盖,因为光标从第一行的第一个字符开始;
f.close()
2、文件修改:
src_f=open('告白气球','r',encoding='utf-8')
data=src_f.readlines()
src_f.close()
dst_f=open('告白气球','w',encoding='utf-8')
# dst_f.writelines(data)
dst_f.write(data[0])
dst_f.close()
3、拷贝文件:
with open('告白气球','r',encoding='utf-8') as src_f,
open('告白气球_new','w',encoding='utf-8') as dst_f:
data=src_f.read()
dst_f.write(data)
说明:使用
with open('a.txt','w') as f:
f.write('1111 ')
的方式操作文件可以自动关闭文件句柄;
with open('告白气球','r',encoding='gbk') as src_f,
open('告白气球_new','w',encoding='utf-8') as dst_f:
data=src_f.read()
dst_f.write(data)
#文件解码后可以转换成其它的编码格式
13.5、文件处理模式之b模式:
# 注意:b模式打开文件时不能指定编码,但也要保证编码和解码的一致性;
1、rb模式:
f = open('告白气球', 'rb')
# b的方式不能指定编码,b的方式不能指定编码
data = f.read()
print(data)
print(data.decode('utf-8'))
# '字符串'---------encode---------》bytes
# bytes---------decode---------》'字符串'
f.close()
2、wb模式:
f = open('告白气球', 'wb')
f.write(bytes('方丈山 ', encoding='utf-8'))
f.write('周杰伦'.encode('utf-8'))
f.close()
3、ab模式:
f = open('告白气球', 'ab')
f.write(bytes('方丈山 ', encoding='utf-8'))
f.write('周杰伦'.encode('utf-8'))
f.close()
4、使用b模式复制文件:
f = open('告白气球', 'rb')
data=f.read()
f.close()
f1 = open('告白气球_new', 'wb')
f1.write(data)
f1.close()
13.6、文件操作的其它方法:
1、newline='' :
f=open('告白气球','r',encoding='utf-8',newline='')
# 在linux下换行符是 ,在windows下换行符是
# python默认做了处理,在windows下使用 作为换行符,隐藏了 (即是隐藏了也占一个字节)
# newline='' 表示不不隐藏windows平台下换行符中的 ,读取文件中真正的换行符号
print(f.tell())
# 光标在文件的第几个字节
print(f.readlines())
f.readline()
print(f.tell())
f.close()
#输出结果如下:
#0
#['塞纳河畔 左岸的咖啡 ', '我手一杯 品尝你的美']
#58
2、绝对位置的seek(默认):
#可以以b模式打开,也可以使用普通文本模式打开
f = open('告白气球', 'r', encoding='utf-8')
print(f.tell())
f.seek(10)
# 等价于f.seek(3,0),表示从开头开始算,将光标移动到第10个字节
print(f.tell())
f.seek(3)
# 从开头开始算,将光标移动到第3个字节
print(f.tell())
data = f.read(3)
# 从文件中读取3个字符
print(data)
#输出结果如下:
#0
#10
#3
#纳河畔
3、相对位置的seek:
# 必须以b的模式打开
f = open('告白气球', 'rb')
print(f.tell())
f.seek(10,1)
# 相对于上一个光标的位置移动10个字节
print(f.tell())
f.seek(3,1)
# 相对于上一个光标的位置移动10个字节
print(f.tell())
#输出结果如下:
#0
#10
#13
4、倒着方式的seek:
# 必须以b的模式打开
f = open('告白气球', 'rb')
print(f.tell())
f.seek(-6, 2)
# 将光标从文件的末尾向前移动6个字节(即两个汉字的位置)
print(f.tell())
print(f.read().decode('utf8'))
# 从现在光标所在的位置往后读
print(f.tell())
#输出的结果如下:
#0
#52
#的美
#58
5、文件截取操作(truncate)
#注意:因为截取是对文件的修改操作,所以必须有写的权限,但是w和w+除外
f = open('告白气球', 'r+', encoding='utf-8')
f.truncate(3)
#从开头开始算,将文件只保留从0-3个字节的内容(即一个汉字)
6、读取日志文件的最后一行:
(1)使用列表的形式:
f=open('日志文件','rb')
data=f.readlines()
print(data[-1].decode())
# 缺点:将所有日志都读出来放进一个列表内,由于该列表是放到内存中的,所以当日志量比较
# 大时会消耗系统的内存;
(2)使用for循环的方式:
f = open('日志文件', 'rb')
for i in f:
print(i.decode('utf8'),end='')
# 优点:从文件中取出一行日志放到内存中,如果不是想要的结果就丢弃,循环该操作,直至找到
# 想要的结果为止,比较节约系统的内存;
(3)读取大文件最后一行(最快的方式):
f = open('日志文件', 'rb')
offs = -10
# 指定偏移量
while True:
f.seek(offs, 2)
# 从文件末尾向前移动10个字节
data = f.readlines()
# 读取光标后面的字节组成列表的形式
if len(data) > 1:
print('文件的最后一行是%s' % (data[-1].decode('utf-8')))
# 取出列表中最后一行
break
offs *= 2
# 列表不满足一行,增大偏移量,进入下一次循环
13.7、小结:
1、f.flush()
#将文件内容从内存刷到硬盘
2、f.closed
#文件如果关闭则返回True
3、f.encoding
#查看使用open打开文件的编码
4、f.tell()
# 查看文件处理当前的光标位置,文件必须可读
5、f.seek(3)
#从开头开始算,将光标移动到第三个字节,文件必须可读
6、f.truncate(10)
#从开头开始算,将文件只保留从0-10个字节的内容,文件必须以写方式打开,但是w和w+除外;
7、read(3)表示从文件中读取3个字节,其余的文件内光标移动都是以字节为单位,比如seek,tell,read,truncate
8、"告白气球"文件内容:
塞纳河畔 左岸的咖啡
我手一杯 品尝你的美
9、日志文件内容:
2019/8/18 lc 今天天气真好
2019/8/19 lc 今天天气真好
2019/8/20 lc 今天天气不好