Python【No-19】文件读写


同步和异步的区别就在于是否等待IO执行的结果。好比你去麦当劳点餐,
你说“来个汉堡”,服务员告诉你,对不起,汉堡要现做,需要等5分钟,于是你站在收银台前面等了5分钟,拿到汉堡再去逛商场,这是 同步IO

你说“来个汉堡”,服务员告诉你,汉堡需要等5分钟,你可以先去逛商场,等做好了,我们再通知你,这样你可以立刻去干别的事情(逛商场),这是异步IO

很明显,使用异步IO来编写程序性能会远远高于同步IO,但是异步IO的缺点是编程模型复杂。想想看,你得知道什么时候通知你“汉堡做好了”,而通知你的方法也各不相同。

如果是服务员跑过来找到你,这是回调模式,如果服务员发短信通知你,你就得不停地检查手机,这是轮询模式。总之,异步IO的复杂度远远高于同步IO。

文件读写其实都是由操作系统完成的,现代操作系统是不允许普通程序直接操作磁盘的,所以读写文件就是请求操作系统打开一个文件对象(又称:文件描述符),通过操作系统提供的接口从这个文件对象中读取数据或写入数据

同步IO

>>> with open(file_path, 'r/w/a') as alias:
···     do sth

r :读
w :覆盖写
a+:追加写

读 read

读取的过程:1. 打开文件;2. 读取文件;3. 关闭文件

  • 第一步:f = open('/user/boii/io_note.txt', 'r')
    用python内置的open()函数打开一个文件对象,
    第一个参数传入读的文件的路径,第二个参数传入r为读取的意思
    如果打开成功,open()会返回一个文件对象
    如果打开失败,open()会抛出一个IOError错误。

  • 第二步:f.read()
    通过read()方法,可以将全部内容读取出来。

  • 第三步:f.close()
    文件打开成功后,必须使用close()方法关闭文件。
    因为文件对象会占用操作系统资源,且操作系统同一时间能打开的文件数量也有限。
    文件打开失败后,会产生IOError,则不会调用f.close()

综合起来可以这么写:

try:
    f = open('/user/boii/io_note.txt', 'r')    # 打开文件
    print(f.read())    # 读取文件
except IOError as e:
    print(e)
else:
    f.close()    # 关闭文件

--------------------------------------------------

# Output:
# 如果文件打开成功,会输出(文件全部内容):io
# 如果文件打开失败,会输出:[Errno 2] No such file or directory: '/user/boii/io_note.txt'

但是这样太繁琐,一点也不符合Python优雅的气质。
所以 Python 引入了with语句来自动帮我们调用close()方法

with open('/user/boii/io_note.txt', 'r') as f:
    print(f.read())
指定字节 read(size)

file_obj.read(size)

read()方法不填写参数,直接读取文件全部内容。如果一个文件太大,全部读取会爆内存的。
所以可以通过指定 size 的方式指定读取 size 个字节的内容。

# io.txt
Hello Python!
I am Boii.
I am learning.

--------------------------------------------------

# io_read.py
with open('io.txt', 'r') as f:
    data = f.read(8)    # 读取前8个字节
    print(data)

--------------------------------------------------

# Output:
Hello Py
跳过字节 seek(size)

file_obj.seek(size)

通过 seek()可以在读取之前跳过 size 个字节,再开始读取

# io.txt
Hello Python!
I am Boii.
I am learning.

--------------------------------------------------

# io_read.py
with open('io.txt', 'r') as f:
    f.seek(3)
    data = f.read(8)    # 读取前8个字节
    print(data)

--------------------------------------------------

# Output:
lo Pytho
读取一行 readline()

file_obj.readline()

readline()方法会读取文件的一行,遇到\n就认为是一行

# io.txt
Hello Python!
I am Boii.
I am learning.

--------------------------------------------------

# io_read.py
with open('io.txt', 'r') as f:
    data = f.readline()    # 读取第一行
    print(data)

--------------------------------------------------

# Output:
Hello Python!

这样只能读取一行,可以使用 while 循环一行一行的读取

# io.txt
Hello Python!
I am Boii.
I am learning.

--------------------------------------------------

# io_read.py
with open('io.txt', 'r') as f:
    data = f.readline()    # 读取第一行
    while data:
        print(data, end='')
        data = f.readline()    # 接着读下一行

--------------------------------------------------

# Output:
Hello Python!
I am Boii.
I am learning.
读取多行 readlines()

file_obj.readlines()

readlines()方法会一次性读取文件中多行内容,最后返回一个 list,一个元素一行内容。

# io.txt
Hello Python!
I am Boii.
I am learning.

--------------------------------------------------

# io_read.py
with open('io.txt', 'r') as f:
    datas = f.readlines()    # 读取多行
    for line in datas:
        print(line, end='')

--------------------------------------------------

# Output:
Hello Python!
I am Boii.
I am learning.

效果是一样的。

写 write

写入的过程:1. 打开文件;2. 写入文件;3. 关闭文件

写入同样可以使用with语句,with语句自动会关闭文件
读文件的时候如果文件不存在,会抛出 IOError 错误
写文件的时候如果文件不存在,会创建文件

写入有两种,一种是覆盖原有内容写入新内容;一种是在原有内容基础上追加新内容。
覆盖写在open()函数中要传入 w,追加写在open()函数中要传入a

写入单行 wirte()
# io_write.py
contend = '''I am the contend which be writed down into file.
Hello Python!'''

with open('io.txt', 'w') as f:
    f.write(contend)    # 写入文件

--------------------------------------------------

# io.txt
I am the contend which be writed down into file.
Hello Python!

写入多行 writelines()

file_obj.writelines(str)

当有多行要写入的时候,除了上面用 '''的多行字符串,可以用 writelines(list)来将内容一次写入。第一个参数接受的是一个 list 列表 或 string 字符串

# io_write.py
datas = ['Hello Python!', 'I am Boii', 'I like coding']
with open('io.txt', 'w') as f:
    f.writelines(datas)    # 写入文件

--------------------------------------------------

# io.txt
Hello Python!I am BoiiI like coding

跟预设结果不一样,并没有换行符。可以直接给datas的每个元素加上\n
但是这种办法很费力,且很多时候内容不是你决定的,这时候 列表生成式 就排上用场了。

# io_write.py
datas = ['Hello Python!', 'I am Boii', 'I like coding']
with open('io.txt', 'w') as f:
    new_datas = [line + '\n' for line in datas]
    f.writelines(new_datas)    # 写入文件

--------------------------------------------------

# io.txt
Hello Python!
I am Boii
I like coding

追加写
# io_write.py
contend = '''I am the contend which be writed down into file.
Hello Python!'''

with open('io.txt', 'a') as f:
    f.write(contend)    # 写入文件

--------------------------------------------------

# io.txt 第一次执行
I am the contend which be writed down into file.
Hello Python!

# io.txt 第二次执行
I am the contend which be writed down into file.
Hello Python!I am the contend which be writed down into file.
Hello Python!

打开模式

打开模式有很多,大致分为:

字符意义
r读取(默认)
w覆盖写
a追加写
x排他性创建,如果文件已存在则失败
b二进制模式
t文本模式(默认)
+可读可写

表中的字符组合起来就有丰富的打开方式
r只读,r+可读可写,rb只读一个二进制文件(图片音视频等)
w只覆盖写,w+可读可覆盖写,wb只覆盖写一个二进制文件
a只追加写,a+可读可追加写,以此类推

字符编码

要读取非UTF-8编码的文件,需要给open()函数传入encoding参数

例如打开一个GBK编码的文件

>>> with open('io.txt', 'r', encoding='gbk') as f:
···    print(f.read())
Hello Python!

但有时候打开的文件编码不规范,混杂了多种编码的字符,
而打开时只能按一种编码打开,所以势必会造成乱码。
这种乱码的处理可以用 errors参数。

open(filepath, mode, encoding='value', errors='value')
errors参数的值有

  • ignore:直接忽略
  • strict:引发ValueError异常。与默认值None效果相同
  • replace_sign:会将错误的地方替换为指定的replace_sign符号
  • 其他
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TCP404

老板大方~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值