文件处理

一、文件处理流程

    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做了什么事情


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值