一、文件处理流程
1、打开文件,得到文件句柄并赋值给一个变量
2、通过句柄对文件进行操作
3、关闭文件
二、文件打开模式
1、r只读(默认打开模式是只读)
2、w只写
3、a追加
三、文件操作实列
1、只读(r)
read读取文件所有内容
#因为使用的是windows客户端默认的是gbk编码,open默认使用系统编码,这里需要指定打开的编码方式为utf-8
f = open('a','r',encoding='utf-8')
#读取全部赋值给变量data
data = f.read()
#打印data内容输出为所有内容
print(data)
readlines一行行读取文件内容,读取到最后一行再往下读取就为空
#因为使用的是windows客户端默认的是gbk编码,open默认使用系统编码,这里需要指定打开的编码方式为utf-8
f = open('a','r',encoding='utf-8')
#print(f.readable())
#最后加参数end为空就不会在打印的时候出现换行
#readline一次读取一行
#readlines读取多行以行为元素返回一个列表
print('第一行',f.readline(),end='')
print('第二行',f.readline())
print('第三行',f.readline())
print('第四行',f.readline())
print('第五行',f.readline())
print('第六行',f.readline())
#最后记得关闭
f.close()
readable查看是否可读取,可读取返回true,不可读取返回false
f = open('a','r',encoding='utf-8')
print(f.readable())
True
2、w 写
如果加入w,则在运行的时候会首先把文件清空,如果文件不存在会建立一个新文件
f = open('a','w',encoding='utf-8')
f.write('1111\n')
f.write('2222\n')
f.close()
运行文件a则清空,写入1111和2222,写操作不会换行,需要换行必须加\n
读写都是以字符串的数据模式,不能是其他任何数据类型。
3、a追加。在文件尾部追加字符串,原字符串保留原样
f = open('a','a',encoding='utf-8')
f.write('写到最后')
4、r+ 读写。可以打印出原文内容并且不换行继续添加字符串
f = open('a','r+',encoding='utf-8')
data=f.read()
print(data)
f.write('123')
如果上面没有data=f.read()这一步直接f.write会从文件开头位置写入并且覆盖从头开始的内容
5、修改文件。加入文件有两行内容aaa、bbb。要删除bbb
#以只读模式打开文件a
src_f = open('a','r',encoding='utf-8')
#读取成一个列表的方式赋值给data
data = src_f.readlines()
src_f.close()
#以写的模式打开一个新文件 没有及生成
dst_f = open('a_new','w',encoding='utf-8')
#把第一行写入文件
dst_f.write(data[0])
dst_f.close()
#print(data)
文件处理最后需要使用close关闭,可以使用with打开则不需要每次关闭,程序会自动关闭
with open('a','w') as f:
f.write('1111\n')
四、文件处理b模式
1、以二进制模式读取文档
#使用二进制打开不能指定编码方式,否则报错
f=open('test11.py','rb')
data=f.read()
print(data)
b'hello1\r\n22222\r\n33333\r\n4444'
在linux中回车使用\n表示,在Windows中使用\n\r表示
2、通过解码把二进制编码成原文档
#使用二进制打开不能指定编码方式,否则报错
f=open('test11.py','rb')
data=f.read()
print(data.decode('utf-8'))<br><br>
hello1
22222
33333
4444
你好好
3、通过二进制编码写入
f=open('test22.py','wb')
f.write(bytes('222\n',encoding='utf-8'))
PS:写入不能直接写入字符串格式,必须先把字符串以utf-8的格式转换成二进制格式然后写入
直接在字符串前面加b也可以(这样值适用于字符和数字如果是中文不可以,还是使用bytes)
f=open('test22.py','wb')
f.write(b'222\n')
直接对字符串使用encode方法也可以
f=open('test22.py','wb')
x='zhangsan'
f.write(x.encode('utf-8'))
4、ab 从文件最后位置往后写参数
f=open('test22.py','ab')
x='zhangsan'
f.write(x.encode('utf-8'))
PS:为什么要使用二进制方式处理文件,因为python默认使用t文本处理,但是不是所有文件都是文本格式可能有其他格式,所以需要使用二进制方式来处理。
五、文件操作的其他方法
1、flush刷新数据到磁盘,类似于文件中的保存操作。不能在pycharm里面演示,可以在python终端演示,写入返回值为光标位置,没有执行flush就不会写入到磁盘,可以打开另外一个终端查看
>>> f=open('test.txt','w')
>>> f.write('11111\n')
6
>>> f.flush()
2、tell取光标当前位置
f=open('a.txt','r+',encoding='utf-8')
print(f.tell())
f.readline()
print(f.tell())
0
9
开始光标在位置0读取了一行以后,光标位置变成位于9
3、encoding显示编码(非原文件编码,而是打开文件的编码)
f=open('a.txt','r+',encoding='utf-8')
print(f.encoding)
utf-8
4、readlines参数读取文件中真正 的换行符号
f = open('a','r',encoding='utf-8')
print(f.readlines())
['dsadjahyduwhha\n', 'sdasdas\n', 'asdasdas\n', 'asdasdsa\n', 'fdsfa']
5、seek控制光标的移动,开始光标位置为0,读取一行后位置为8,使用seek方法又放置在了0位置
f=open('a.txt','r',encoding='utf-8')
print(f.tell())
f.readline()
print(f.tell())
f.seek(0)
print(f.tell())
0
8
0
PS:seek是以字节为单位的,假如文件含有中文seek到位置1,因为一个中文是3个字节所以打印会出现错误。如果是英文因为英文一个字符就是一个字节所以打印不会报错。
f=open('a','r',encoding='utf-8')
print(f.tell())
f.readline()
print(f.tell())
f.seek(3)
print(f.tell())
print(f.readlines())
seek(3)代表读取3个字符(一个中文代表一个字符一个英文也代表一个字符),其余的文件内光标移动都是以字节为单位如seek,tell,read,truncate
6,truncate截取,以可写方式打开从头开始截取多少个字节
f=open('a.txt','r+',encoding='utf-8')
f.truncate(10)
7,seek的方法补充
seek指定位置的方式是从0绝对值开始指定的day17-12.py 默认对比位置是0不需要加0参数及默认
#打开文件
f=open('seek.txt','rb')
#打印位置为0
print(f.tell())
#指定位置10所以打印为0
f.seek(10)
print(f.tell())
f.seek(3)
print(f.tell())
0
10
3
参数1 代表相对位置相对于上一次光标停留的位置
#打开文件
f=open('seek.txt','rb')
#打印位置为0
print(f.tell())
#指定位置10相对上一次光标的位置所以打印为10
f.seek(10,1)
print(f.tell())
#指定位置3相对上一次光标的位置所以打印为13
f.seek(3,1)
print(f.tell())
0
10
13
参数2代表从文件末尾开始seek,相当于倒叙
#打开文件,因为seek是用字节所以要以二进制方式打开
f=open('seek.txt','rb')
#打印位置为0
print(f.tell())
#从末尾seek5个字符
f.seek(-5,2)
print(f.tell())
0
18
seek.txt的内容为
hello
你好
123
123
从后往前倒数5个是123以及第3行末尾的\r\n 然后在从前往后数hello + \r\n 7个字节 你好+|\r\n 8个字节 123 3个字节所以位置是18
PS:使用参数2前面倒序的数字必须是负数否则seek的位置不正常
上面后面使用read方法读取出来的内容为 b'\r\n123'
seek参数2的作用,假如是读取日志文件最后一行可以使用以下方法
f=open('日志文件','rb')
data=f.readlines()
print(data[-1].decode('utf-8'))
但是使用以上方法会一次性把所有内容读取到内存造成内存的浪费,下面使用seek方法实现
f=open('日志文件','rb')
for i in f:
#定义偏移量
offs=-10
while True:
#从后往前面读取偏移量的字节
f.seek(offs,2)
#一次性读取从光标位置往后的内容生成一个列表如果
data=f.readlines()
#如果列表长度大于1则代表至少读取到了两行则取最后一行并且结束无限循环
if len(data) > 1:
print('文件的最后一行是%s' %(data[-1].decode('utf-8')))
break
#如果列表长度不满足要求既等于1则加大偏移量再从后往前读取一次
offs*=2
2017-01-05 xxx做了什么事情