Python的with open

发布时间 2023-12-04 20:26:49作者: JessicaJJmm

1、文件的基本操作

1. 打开文件
2. 操作文件
3. 关闭文件
 
关键字:open

方式1

f=open(r'a.txt', 'r', encoding='utf-8')
# f = open(r'a.txt', mode='r', encoding='utf-8')
res = f.read()
print(res)
# # 关闭文件:释放资源的
# f.close()

方式2

# with上下文管理器
with  open('a.txt', 'r', encoding='utf8') as f:
    print(f.read())

2、文件的读写模式

1
2
3
4
5
6
7
8
9
r:read(读)
w:write(写)
a:append(追加写)
 
# 读模式
# 1. 路径不存在,直接保存
# with open('a.txt', 'r', encoding='utf8') as f:
#     pass
 
# 2. 路径存在
# with open('a.txt', 'r', encoding='utf8') as f:
#     print(f.read())
 
# 写模式
# 1. 路径存在,文件不存在, 会自定创建出来文件
# with open('a.txt', 'w', encoding='utf8') as f:
#     pass
 
# 2. 路径存在
# 把文件内的原本数据情况掉,从新写入,覆盖!!!
# w模式很危险,
# with open('a.txt', 'w', encoding='utf8') as f:
# # f.write('hello big baby!')
# f.write(str(123)) # 写文件的数据类型必须是字符串类型,和字节类型,其他类型都不能直接写入,
 
 
# 3. 追加模式
# 3.1 路径不存在,会自动创建文件出来
with open('a.txt', 'a', encoding='utf8') as f1:
    f1.write('hello baby!')
 
# 路径存在,在文件的原来数据后面继续追加新的内容
with open('a.txt', 'a', encoding='utf8') as f1:
   f1.write('hello baby!\n')

补充:

readlines(): 该方法用于一次性读取整个文件,并将内容存储为一个列表,其中列表的每个元素是文件的一行内容。每行末尾的换行符也会被包含在内。

readlines()方法会一次性将整个文件加载到内存中,如果文件较大,可能会消耗大量的内存资源。

readline(): 该方法用于逐行读取文件内容。每次调用readline()方法,会返回文件的下一行内容(包括行尾的换行符)。下一次调用readline()方法会返回文件的下一行,以此类推,直到文件末尾。

3、文件的读操作优化

复制代码
with open('a.txt', 'r', encoding='utf8') as f:
    '''
        read方法它是一次性读取文件的所有内容,所以,当文件内容非常大的时候,有可能会造成内存溢出
        我们不允许内存溢出的情况出现,但是当文件内容非常小的时候,无所谓了,
        
        针对上述出现的问题,如何解决呢?
    '''
    # print(f.read()) # 一次性把文件中的内容读取完毕
    # 变量f它值支持for循环的
    for line in f:
        print(line)  # for循环就是一行一行的读取内容的
        '''所以,以后读文件的时候,如果觉得文件很大,我们就是要for循环一行一行的读取'''
复制代码

4、文件的操作模式

t 模式:text文本

r >>> rt
w >>> wt
a >>> at
 
"""
1. 它是以字符串位基本单位(写文本内容,如汉字、字母)
2. 它只能操作字符串形式
3. encoding参数必须写
"""

b模式:bytes二进制模式(读写音、视频文件只能用b模式)

r >>> rb
w >>> wb
a >>> ab
"""
1. b不能省略,必须写 rb
2. 它可以操作任意的数据类型:视频、音频、图片等都可以
3. encoding参数必须不能写
4. 它的数据以字节为单位了(任何数据都转为二进制去操作,所以单位是字节)
"""

操作图片案例

# 做一个简易版本的拷贝工具
 
source_file_path = input(r'请输入你想要拷贝的原文件路径(如:r"C:\path\to\file"):')
# /Users/sanpangdan/Desktop/python_fullstack/10018.jpg
 
target_file_path = input(r'请输入你想要拷贝到的目标路径(如:r"C:\path\to\file"):')
# /Users/sanpangdan/Desktop/python_fullstack/aa/ccc.jpg
 
# 定义一个函数
def  copy_file(source_file_path, target_file_path):  # 源路径和目标路径作为形参
    with  open(source_file_path, 'rb') as source_file:  # 二进制读模式打开源文件,别名为 source_file
        with  open(target_file_path, 'wb') as target_file:  # 二进制写模式打开目标文件地址,别名为target_file
            target_file.write(source_file.read())  # f.write,写的内容来自上一层的读内容
    print(f"Copy {source_file_path} to {target_file_path} succeeded.")  # 打印复制成功提示
 
copy_file(source_file_path, target_file_path)  # 执行函数,带入用户输入的实参

5、读写混合

with open 不直接支持 'wr' 模式。但是可以使用 'w+' 或 'r+' 模式来同时进行读和写操作。两者之间有一些区别:

'w+' 模式:打开文件用于读写。如果文件存在,则会清空文件内容;如果文件不存在,则创建一个新文件。(危险)

with open('file.txt', 'w+') as file:
    file.write('Hello, world!')
    file.seek(0)  # 将文件指针移回文件开头
    content = file.read()
    print(content)

'r+' 模式:打开文件用于读写。如果文件存在,文件指针会定位在文件开头;如果文件不存在,则会报错。

with open('file.txt', 'r+') as file:
    file.write('Hello, world!')
    file.seek(0)  # 将文件指针移回文件开头
    content = file.read()
    print(content)

‘a+’ 模式(指针在文件末尾)

>>> f = open("sample.txt", "a+")
>>> f.write("this is a test")
14
>>> f.read()
''
>>> f.seek(0)
0
>>> f.read()
'this is a test'

 

a+:“a”为只可追加不可读,“+”为可读可写,“a+”打开一个文件用于读写,如果该文件已存在,文件指针将会放在文件的结尾,且文件打开时会是追加模式。如果该文件不存在,会创建新文件用于读写。

6、文件指针的移动 

读取指定的字符个数

with  open('file.txt', 'rb') as file:
    content = file.read(6)
    print(content.decode('utf-8'))

 

一个汉字在utf-8编码中占据3个字符,所以read 6个字符只能读出2个汉字

指针的移动:总共有三种模式:

f.seek(3,0)
f.seek(offset,whence)

whence: 

0: 默认的模式,该模式代表指针移动的字节数是以文件开头为参照的(支持tb模式)

1: 该模式代表指针移动的字节数是以当前所在的位置为参照的(只用于字节b模式) 

2: 该模式代表指针移动的字节数是以文件末尾的位置为参照的(只用于字节b模式)

with  open('file.txt''rb') as f:
    f.seek(3,0)
    print(f.read())
    f.seek(-3,1)  # 负数代表的是往相反方向移动
    f.seek(-7,2)  # 负数代表的是往相反方向移动
    print(f.tell()) # 查看光标现在移动的位置
    print(f.read())  # loworld

7、文件内容的修改

复制代码
with open('file.txt', 'r', encoding='utf8') as f:
    data = f.read()
res = data.replace('tank', 'tank12')
print(res)

with open('file.txt', 'w', encoding='utf8') as f:
    f.write(res)
复制代码

8、简易图片复制功能

记忆点:r 表示转译,字符串使用占位符。for循环打开,防止大文件内存溢出

with open(r'%s' % source_file_path, 'rb') as f:
    with open(r'%s' % target_file_path, 'wb') as f1:
        # 以r模式打开源文件,以w模式打开目标文件
        for line in f:
            f1.write(line)

9、小练习:实现动态查看最新一条日志的效果

复制代码
import time  # tail -f a.txt

with open('file.txt', mode='rb') as f:
    f.seek(0, 2)  # 直接把光标移动到了末尾
    while True:
        line = f.readline()  # 读取一行数据
        if len(line) == 0:
            # 没有内容
            time.sleep(1)  # 睡眠0.5秒
        else:
            print(line.decode('utf-8'), end='')
复制代码

注解:

1、f.seek(0,2)偏移量为0,2模式指针在文件的末尾

2、当在文件末尾添加字符时候,循环语句的代码块起作用,读入数据