返回顶部

Python 之文件处理open功能——模式介绍

Python 之文件处理open功能——模式介绍

文件是操作系统提供给用户/应用程序操作硬盘的一种虚拟的概念/接口。 用户/应用程序可以通过文件将数据永久保存的硬盘中,即操作文件就是操作硬盘。

用户/应用程序直接操作的是文件,对文件进行的所有操作都是在向操作系统发送系统调用,然后再由操作将其转换成具体的硬盘操作

open()功能使用的模块

t文本模块(默认)、x只写模式、b二进制模式,r只读模式,w只写模式,a只追加模式,+模式

控制文件读写内容的模式,t和b模式不能单独使用,必须跟r,w,a连用

t 文本模式(默认)

文本模式读写都是以str(unicode)为单位

必须是文本文件

必须指定字符编码  encoding=‘utf-8’

t模式会将f.read()读出的结果解码成unicode

#没有指定encoding参数操作系统会使用自己默认的编码,LInux系统默认utf-8,Windows系统默认gbk

with open('a.txt',mode='rt',encoding='utf-8') as f: ###指定编码

rt:硬盘的二进制读入内存 >> t模式会将读入内存的内容进行decoding解码操作

rb: 硬盘的二进制读入内存 >> b模式下,不做任何转换,直接读入内存

t和b模式总结

1.在操作纯文本文件方面,t模式省去了编码和解码环节,b模式则需要手动编码和解码

2.在针对非文本文件(如:图片,视频,音频等)只能使用b模式

x只写模式

x只写模式,不可读:文件不存在创建,文件存在报错

>>> with open('g.txt',mode='x',encoding='utf-8') as f:
    f.read()
>>> with open('a.txt',mode='x',encoding='utf-8') as f:
     f.write('aaabbc')
# cat a.txt
aaabbc

b二进制模式

内存: utf-8格式的二进制 >> 解码 >> unicode

硬盘: (c.txt内容:utf-8格式的二进制)

bytes类型 >> 当成二进制

得到bytes类型的三种方式:

1.字符串编码之后的结果

2.b'纯英文字符'

3.b模式下打开文件,f.read()读出内容

rb: 硬盘的二进制读入内存 >> b模式下,不做任何转换,直接读入内存

1.读写都是以bytes为单位

2.可以针对所有文件

3.一定不能指定字符编码,即一定不能指定encoding参数

>>> with open(r'g.txt',mode='rb') as f:
     res=f.read()
     print(res)
b'111\n222\n333\n444\n555\n'

#将二进制文件转换为utf-8
>>> with open(r'g.txt',mode='rb') as f:
     res=f.read()
     print(res,type(res))
     print(res.decode('utf-8'))
     print(res,type(res))
     
>>> with open(r'g.txt',mode='wb') as f:
...     f.write('aaa')
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
TypeError: a bytes-like object is required, not 'str'

>>> with open(r'g.txt',mode='wb') as f:
     f.write('你好'.encode('utf-8'))
     f.write('你好'.encode('gbk'))        #双编码会出现部分识别,部分乱码

----------------- #  拷贝工具【文本,图片,视频】---------------
#!/bin/python3
# -*- coding: utf-8 -*-
src_file=input('源文件路径:').strip()
dst_file=input('源文件路径:').strip()

with open(r'{}'.format(src_file),mode='rb') as f1,\
    open(r'{}'.format(dst_file),mode='wb') as f2:
    #res=f1.read()        #文件过大时,会造成内存占用过大
    #f2.write(res)
    for line in f1:
        f2.write(line)

# python3 r4.py
源文件路径:g.jpg
源文件路径:d.jpg

--------------# 当文件过大过长会占用较大内存,需要循环去读
#循环读取文件
#方式一: while 适用于文件较大,一行较长,自己控制每次读取文件的数据的数据量
with open(r'g.jpg',mode='rb') as f:
    while res:
        res=f.read(1024)
        if not res:
            break
        print(len(res))

with open(r'g.jpg',mode='rb') as f:
    while True:
        res=f.read(1024)
        if  len(res) == 0:
            break
        print(len(res))

#方式二:for 以行为单位读,当一行内容过长时会导致一次读入内容的数据量过大
--------# rt
with open(r'g.txt',mode='rt',encoding='utf-8') as f:
    for line in f:
        print(line)
你好
---------#  rb
with open(r'g.jpg',mode='rb') as f:
    for line in f:
        print(line)
b'\xe4\xbd\xa0\xe5\xa5\xbd\n'
b'\xe4\xb8\xad\xe5\x8d\x8e\n'
b'88\n'

r只读模式

以t模式为基础进行内存操作: r,w,a

r默认的操作模式: 只读模式,当文件不存在时报错,当文件存在时,文件指针跳到开始位置

with open('a.txt',mode='rt',encoding='utf-8') as f:
    l=f.read()    #把所有内容从硬盘读入内存
    print(l)
with open('a.txt',mode='rt',encoding='utf-8') as f:        #未添加此行则下面不会打印,文件指针未跳转,文件有换行则输出也会有换行
    l2=f.read()    #把所有内容从硬盘读入内存
    print(l2)


-------
# cat user.txt
wei:123

# cat r.py
#!/bin/python3
# -*- coding: utf-8 -*-

inp_username=input('you name:').strip()
inp_password=input('you password:').strip()
with open('user.txt',mode='rt',encoding='utf-8') as f:
    res=f.read()
    username,password=res.strip().split(':')

if inp_username == username and inp_password == password:
    print('login successfull')
else:
    print('username or password error')


# python3 r.py
you name:wei
you password:123
login successfull

-------------------------------------------
# cat r1.py
#!/bin/python2
# -*- coding: utf-8 -*-

with open('user.txt',mode='rt',encoding='utf-8') as f:
    for line in f:
        print(line,end='')

# python3  r1.py
wei:123
li:111
zhang:222
wang:333

-------------------------###根据文件账户密码进行查询,登录实例---------------------
# cat user.txt
wei:123
li:111
wang:222
zhang:333

# cat r1.py
#!/bin/python3
# -*- coding: utf-8 -*-
inp_username=input('you name:').strip()
inp_password=input('you password:').strip()
with open('user.txt',mode='rt',encoding='utf-8') as f:
    for line in f:
        #print(line,end='') #wei:wei\n
        username,password=line.strip().split(':')

        if inp_username == username and inp_password == password:
            print('login successfull')
            break
    else:
        print('username or password error')

# python3 r1.py
you name:wei
you password:123
login successfull
# python3 r1.py
you name:li
you password:111
login successfull
# python3 r1.py
you name:wang
you password:222
login successfull
# python3 r1.py
you name:zhang
you password:333
login successfull

----------------------------------------------------------
# cat user.txt
wei:123
li:111
wang:222
zhang:333

# python3 r1.py
#!/bin/python3
# -*- coding: utf-8 -*-

name=True
while name:
    inp_username=input('you name:').strip()
    inp_password=input('you password:').strip()
    with open('user.txt',mode='rt',encoding='utf-8') as f:
        for line in f:
            #print(line,end='') #wei:wei\n
            username,password=line.strip().split(':')

            if inp_username == username and inp_password == password:
                print('login successfull')
                name=False
                break
        else:
            print('username or password error')

# python3 r1.py
you name:wei
you password:121
username or password error
you name:wei
you password:123
login successfull

w只写模式

w只写模式,当文件不存在时,会创建空文件,当文件存在时会w会清空文件,指针位于开始位置,w模式打开就会被清空再把后面写入内容覆盖进去

w模式创建新文件:

1.在以w模式打开文件,没有关闭的情况下,连续的写入,新的内容总是跟在旧的内容之后

2.如果重新以w模式打开文件则会清空文件

with open('a.txt',mode='wt',encoding='utf-8') as f:
    f.read()                #文件不可读
    f.write('ojbk\n')        #向文件写入ojbk
    f.write('ojbk\n')
    f.write('ojbk\n')        #在以w模式打开文件没有关闭的情况下,连续的写入,新的内容总是跟在旧的之后

--------#  文件的copy工具【文本】-----------------
# cat r3.py
#!/bin/python3
# -*- coding: utf-8 -*-
with open('a.txt',mode='rt',encoding='utf-8') as f1,\
    open('e.txt',mode='wt',encoding='utf-8') as f2:
    res=f1.read()
    f2.write(res)

# cat a.txt
zhongguo
中华

# python3 r3.py
# cat e.txt
zhongguo
中华

-------------------------------------
# cat r3.py
#!/bin/python3
# -*- coding: utf-8 -*-
src_file=input('源文件路径:').strip()
dst_file=input('源文件路径:').strip()

with open(r'{}'.format(src_file),mode='rt',encoding='utf-8') as f1,\
    open(r'{}'.format(dst_file),mode='wt',encoding='utf-8') as f2:
    res=f1.read()
    f2.write(res)

# cat a.txt
zhongguo
中华

# python3 r3.py
源文件路径:a.txt
源文件路径:c.txt
# cat c.txt
zhongguo
中华

 

a只追加模式

a只追加写,在文件不存在的时候会创建空间文件,在文件存在时文件指针会直接跳到末尾

a模式用来在原有的文件内存的基础上写入新的内容,如:记录日志,注册等

with open('a.txt',mode='at',encoding='utf-8') as f:
    f.read()               #报错不能读
    f.write('aaa')        #可以写入,连续写入

#a模式用来在原有的文件内存的基础上写入新的内容,如记录日志,注册
-----------实现注册功能----------------------
# cat r2.py
#!/bin/python3
# -*- coding: utf-8 -*-

name=input('you name:').strip()
pwd=input('you password:').strip()
with open('db.txt',mode='at',encoding='utf-8') as f:
    f.write('{}:{}\n'.format(name,pwd))

# python3 r2.py
you name:wei
you password:123
# python3 r2.py
you name:wang
you password:222
# cat db.txt
wei:123
wang:222

w与a模式异同

相同点:

在打开的文件不关闭的情况下,连续的写入,新写的内容总会跟在前写的内容后

不同点:

a模式重新打开文件不会清空原文件内容,会将文件指针直接移动到文件末尾新写内容,

w模式重新打开文件会清空原文件内容

w模式用于:创建新文件,记录日志

a模式用于:针对老文件【日志,记录等】

+模式

+可读可写,+不能单独使用,必须配合r,w,a

r+t:  文件不存在直接报错

w+t:  文件不存在直接创建

a+t:  文件追加进去

###############  r+t
>>> with open('g.txt',mode='r+t',encoding='utf-8') as f:
    #print(f.read())            #文件不存在会报错
    f.write('aaa')            #内容写到开头,若是前面有打印输出会在后面追加
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: 'g.txt'
>>> with open('g.txt',mode='w+t',encoding='utf-8') as f:
     ...
>>> with open('g.txt',mode='a+t',encoding='utf-8') as f:
    ...
>>> with open('t.txt',mode='a+t',encoding='utf-8') as f:

###############  w+t
>>> with open('g.txt',mode='w+t',encoding='utf-8') as f:
     print(f.read())        #文件不存在不会报错,会创建
>>> with open('g.txt',mode='w+t',encoding='utf-8') as f:
     f.write('111\n')
     f.write('222\n')
     f.write('333\n')
     print('====>',f.read())

# cat g.txt
111
222
333

###############  a+t
>>> with open('g.txt',mode='a+t',encoding='utf-8') as f:
    print(f.read())        #文件读不出来
    f.write('444\n')    #文件写入
    f.write('555\n')
    print(f.read())        #文件读不出来

# cat g.txt
111
222
333
444
555

控制文件指针移动 seek

指针移动的单位都是以bytes/字节为单位

只有一种情况: t模式的read(n),n代表的是字符个数

seek移动字节指针,tell文件指针当前位置

只有0模式可以在t模式下使用,1,2模式必须在b模式下使用

seek(n,模式)模式:

  模式0: 参照物是文件开头位置
  模式1: 参照物是当前指针所在位置
  模式2:参照物是文件末尾位置,应该倒着移动

# cat g.txt
abc你我他
>>> with open('g.txt',mode='rt',encoding='utf-8') as f:
     res=f.read(4)
     print(res)
abc你

f.seek(9,0)
f.seek(3,0)         #3
f.seek(9,1)
f.seek(3,1)        #12
f.seek(-9,2)        #3
f.seek(-3,2)        #9


#f.tell #获取文件指针当前位置

>>> with open('g.txt',mode='rt',encoding='utf-8') as f:
     f.seek(2,0)



--------------------#  案例
>>> with open('g.txt',mode='rb') as f:
     f.seek(9,0)
     f.seek(3,0)
     print(f.tell())
9
3
3
>>> with open('g.txt',mode='rb') as f:
     f.seek(9,0)
     f.seek(3,0)
     res=f.read()
     print(res.decode('utf-8'))
9
3
你我他

>>> with open('g.txt',mode='rb') as f:
     f.seek(9,1)
     f.seek(3,1)
     print(f.tell())
9
12
12
>>> with open('g.txt',mode='rb') as f:
     f.seek(9,1)
     f.seek(3,1)
     res=f.read()
     print(res.decode('utf-8'))
9
12

>>> with open('g.txt',mode='rb') as f:
     f.seek(-9,2)
     f.seek(-3,2)
     print(f.tell())
4
10
10

# cat  g.txt
aasdasdasdas
>>> with open('g.txt',mode='rb') as f:
     f.seek(-9,2)
     f.seek(-3,2)
     print(f.read().decode('utf-8'))
4
10
as     
 
 #!/bin/python3
# -*- coding: utf-8 -*-
with open('g.txt',mode='rt',encoding='utf-8') as f:
    for line in f:
        print(line.strip())
    while True:
        line=f.read(1024)
        print(line.strip())
        if len(line) == 0:
            break
----------------------# f.seek实现tail功能
# cat  r6.py
#!/bin/python3
# -*- coding: utf-8 -*-
import time
with open('access.log',mode='rb') as f:
    #1.将指针跳到文件末尾
    #f.read()  错误写法,文件较大会有内存溢出
    f.seek(0,2)
    while True:
        line=f.readline()
        if len(line) == 0:
            time.sleep(0.3)
        else:
            print(line.decode('utf-8'))


写入文件追加
# cat a.py
#!/bin/python3
# -*- coding: utf-8 -*-
with open ('access.log',mode='at',encoding='utf-8') as f:
    f.write('20220503  wei')

# python3 a.py
# python3 a.py

# python3 r6.py    #实现tail追加显示文件内容
20220503  wei
20220503  wei    

 

posted @ 2022-05-04 22:32  九尾cat  阅读(780)  评论(0编辑  收藏  举报