Python全栈day17(文件处理)

一,文件处理流程

  1. 打开文件,得到文件句柄并赋值给一个变量
  2. 通过句柄对文件进行操作
  3. 关闭文件

二,文件打开模式

  1. r只读 (默认打开模式是只读)
  2. w只写
  3. a追加

三,文件操作实例

   1.r读

    read读取文件所有内容 vim day17-2.py  文件a为一段文本

#因为使用的是windows客户端默认的是gbk编码,open默认使用系统编码,这里需要指定打开的编码方式为utf-8
f = open('a','r',encoding='utf-8')
#读取全部赋值给变量data
data = f.read()
#打印data内容输出为所有内容
print(data)

When we asks parents for money and for other things, we are so naturally to do it and without thinking too much. If our parents refuse, we will be angry. But the fact is that they don’t owe us, instead, we owes them and most of us don’t know the meaning of gratitude.

    readline一行行读取文件内容vim day17-3.py readline是一行行读取,读取到最后一行以后再往下读取则为空

#因为使用的是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()

第一行 When we asks parents for money and for other things,
第二行 we are so naturally to do it and without thinking too much.

第三行 If our parents refuse, we will be angry.

第四行 But the fact is that they don’t owe us, instead,

第五行 we owes them and most of us don’t know the meaning of gratitude.

第六行 

    readable查看是否可读取,可读取返回True,不可读取返回False

f = open('a','r',encoding='utf-8')


print(f.readable())

True

  2,w写

    如果加入参数w则在运行的时候会首先把文件内容清空,如果文件不存在会新建一个文件vim  day17-4.py

f = open('a','w',encoding='utf-8')
f.write('1111\n')
f.write('2222\n')
f.close()

    运行则文件a内容清空 写入1111和2222,写操作不会换行需要换行必须加入\n

  PS:读写都是以字符串的数据模式不能是其他任何数据类型

  3,a追加vim  day17-5.py 在文件尾部追加‘写到文件最后’字符串,原字符串保留原样。

f = open('a','a',encoding='utf-8')
f.write('写到文件最后')

  4,r+ 读写 vim day17-6.py 可以打印出原文件内容并且不换行继续添加字符串

f = open('a','r+',encoding='utf-8')
data=f.read()
print(data)
f.write('123')

  如果上面没有data=f.read()这一步直接f.write会从文件开头位置写入并且覆盖从头开始的内容

  5,修改文件假如文件a里面有两行内容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,以二进制模式读取文档vim day17-9.py

#使用二进制打开不能指定编码方式,否则报错
f=open('test11.py','rb')
data=f.read()
print(data)

b'hello1\r\n22222\r\n33333\r\n4444'

  PS:在linux中回车使用\n表示在windows中使用\n\r表示

  2,通过解码把二进制编码成原文档

#使用二进制打开不能指定编码方式,否则报错
f=open('test11.py','rb')
data=f.read()
print(data.decode('utf-8'))

hello1
22222
33333
4444
你好好好

  3,通过二进制编码写入vim day17-10.py

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,newline参数读取文件中真正的换行符号

f=open('a.txt','r',encoding='utf-8')
print(f.readlines())

['你好\n', '你好']

  此列为windows里面的python自动把换行符转换成\n,如果需要读取真正的windows下面的换行符加参数newline

f=open('a.txt','r',encoding='utf-8',newline='')
print(f.readlines())

['你好\r\n', '你好']

  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.txt','r',encoding='utf-8')
print(f.tell())
f.readline()
print(f.tell())
f.seek(1)
print(f.tell())
print(f.readlines())

  read(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代表相对位置相对于上一次光标停留的位置day17-13.py

#打开文件
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相当于倒序day17-14.py

#打开文件,因为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的作用,假如是读取日志文件最后一行可以使用以下方法day17-15.py

f=open('日志文件','rb')
data=f.readlines()
print(data[-1].decode('utf-8'))

  但是使用以上方法会一次性把所有内容读取到内存造成内存的浪费,下面使用seek方法实现day17-16.py

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

  

posted @ 2018-01-10 13:55  minseo  阅读(198)  评论(0编辑  收藏  举报