【笔记】Python基础三:文件

时间:2021-10-15 08:49:44

一,文件操作

(一),文件处理流程

1,打开文件,获得文件句柄(open函数提供)并赋值

2,通过句柄对文件进行操作

3,关闭句柄

f = open('陈粒',encoding='utf-8')#open函数会先检索系统的编码gbk,文件存的是UTF-8编码,这样会出现乱码
data = f.read()
print(data)
f.close() f = open('XXX')#把XXX使用gbk编码保存在硬盘上,然后打开不会乱码
data = f.read()
print(data)
f.close()

(二),文件打开模式:

1,文件读操作,r只读

f = open('XXX','r')#XXX使用gbk编码
#data = f.read()
#print(data)
#输出文件内容
print(f.readable())#是否可读
#输出True
# print('第一行',f.readline(),end='')#readline,一次读取一行
# print('第二行',f.readline())#注意如果前面的f.read()读取了文件内容,则使用readline时,游标在文件尾,print不会显示内容
# print('第三行',f.readline())#如果文件没有第三行,则输出空,此时游标在文件尾
print('读取到列表',f.readlines())
#输出:读取到列表 ['1111\n', '2222\n', '\n']
f.close()

2,文件写操作,w只写

f = open('陈粒2','w',encoding='utf-8')#w写模式如果文件存在会把文件清空后再操作,文件不存在则新建
#f.read()#使用写模式打开,读会报错
#输出:io.UnsupportedOperation: not readable
f.write('11111\n')
f.write('22222\n')
f.write('333\n444\n555\n')
#f.writable()
f.writelines(['666\n',''])#写一个列表到文件
#f.writelines(['666\n','777',1])#写的内容必须是字符串,如果有数字存在会报错
#输出:TypeError: write() argument must be str, not int
f.close()

3,文件追加操作,a添加

f = open('陈粒2','a',encoding='utf-8')
f.write('\n写到文件最后')
f.close()

4,文件处理其它模式,r+,可读,可写

#r+模式,可读可写
f = open('陈粒2','r+',encoding='utf-8')
data = f.read()
print(data)
f.write('写测试')
f.close()

5,文件处理B(二进制)模式

1),open默认使用t方式(文本)打开文件,但如果文件是图片,视频等就不适用文本方式打开,需要改用b方式打开

2),二进制方式可以跨平台使用

3),使用举例:

#读二进制方式打开rb,需要解码
#f = open('test11.py', 'rb', encoding='utf-8') # b的方式不能指定编码
f = open('test11.py', 'rb')
data = f.read()
#'字符串'---------encode---------》bytes
#bytes---------decode---------》'字符串'
print(data.decode('utf-8')) #要想显示正常,需要decode,并指定解码类型
#写二进制方式打开wb,需要编码
f = open('test22.py','wb')
#f.write('11111\n') #报错,字符串以二进制形式写入,需要指定编码类型
f.write(bytes('11111\n',encoding='utf-8'))#使用bytes函数转换
f.write('杨戬'.encode('utf-8')) #使用字符串本身的encode方法转换
#追加二进制方式ab,在文件最后一个位置添加
f = open('test22.py','ab')
f.write('yangjian'.encode('utf-8'))

(三),文件处理的一些方法

写文件时游标的位置

#打开文件后,游标位于开头,故从开头开始写,覆盖原有内容
f = open('陈粒2','r+',encoding='utf-8')
test = '写在头部'
test1 = bytes(test,encoding='utf-8')
print(len(test1))
#输出:12 表示占用12个字节
test2 = '111\n222\n33'
print(len(test2))
#输出:10 表示占用10个字节
f.write(test)
#在陈粒2文件的开头部分 111\n222\n33 被'写在头部'占用,从字节上看差了2个
f.close()

readlines和writelines操作列表,每一行是一个列表元素

#文件修改,只剩第一行
src_f = open('xxx','r',encoding='gbk')
data = src_f.readlines()
src_f.close()
dst_f = open('xxx','w',encoding='gbk')
dst_f.writelines(data[0])
dst_f.close()

打开文件后,无需手动关闭,使用关键字with

with open('a.txt','w') as f:
f.write('1111\n') #使用with,复制文件内容到新文件
#src_f=open('xxx','r',encoding='gbk')
#dst_f=open('xxx','w',encoding='gbk')
with open('xxx','r',encoding='gbk') as src_f,\
open('xxx_new','w',encoding='gbk') as dst_f:
data=src_f.read()
dst_f.write(data)

flush,tell,newline=

f = open('a.txt','r',encoding='utf-8')
#f.close()
print(f.closed) #文件是否关闭
print(f.encoding)#文件打开的编码,跟源文件在硬盘上怎么存储没有关系
#f.flush()#从内存保存到硬盘,可以在终端内测试,打开文件写入内容,但是硬盘上文件并没有内容,然后使用flush保存再查看内容
print(f.tell())#当前游标所在位置 0
f.readline()#读取一行移动游标到行尾
print(f.tell())#当前游标所在位置
f.close() f = open('a.txt','r',encoding='utf-8',newline='')#使用newline关键字不让python自动处理\r,自动处理是python为跨平台准备的
print(f.readlines())
f.close()
#输出:['你好,你好\r\n']

注意:read(3)代表读取3个字符,其余的文件内游标移动都是以字节为单位,如seek,tell,truncate

#f.read()读取的是字符,不是字节
f = open('a.txt','r',encoding='utf-8')
print(f.read(3))
print(f.tell())#read以字符计算,但是tell仍以字节计算
f.close()
#输出
'''
你好,
9
'''

seek游标位置移动

f = open('a.txt','r',encoding='utf-8')
print(f.tell())
f.seek(3)
print(f.tell())
print(f.read())
f.close()
#输出
'''
0
3
好,你好
'''
#seek补充
#1模式,相对位置
f = open('seek.txt','rb')
print(f.tell())
f.seek(10)
print(f.tell())
f.seek(3)
print(f.tell()) #输出:3,默认从文件头开始计算
f.seek(5,1) #1模式,相对上一次位置移动,但是打开文件方式必须加b,二进制方式打开。二进制打开不能指定编码
print(f.tell()) #输出:8
f.close() #2模式,文件尾往回数
f = open('seek.txt','rb')
print(f.tell())
f.seek(-5,2) #2模式,从文件末尾开始seek,但是seek值必须是负数
print(f.tell())
print(f.read()) #输出b'\r\n123
f.close() #循环文件技巧
f = open('日志文件','rb')
for i in f: #使用f而不是f.readlines(),可以避免在内存中生成大列表
print(i)
f.close() #使用场景,日志文件很大,一般读取最后一行
f = open('日志文件','rb') for i in f:
offs = -3
while True:
f.seek(offs,2)
data = f.readlines()
if len(data) > 1: #如果倒数读取了一行多,打印,结束循环
print('最后一行%s'%(data[-1].decode('utf-8')))
break
offs *= 2 #如果还不到一行,增加offs继续试探
#输出:最后一行2016/12/30 sb 干了件sb事情

truncate文件截断,属于先读文件后写文件,一般r+打开

f = open('a.txt','r+',encoding='utf-8')
f.truncate(6)#从文件头开始保留6个字节,其余删除