博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python asyncio文件操作_Python中使用asyncio封装文件读写详解及实例
阅读量:5899 次
发布时间:2019-06-19

本文共 1399 字,大约阅读时间需要 4 分钟。

本文主要给大家简单讲解如何用 asyncio.Future对象来封装文件的异步读写。有需要的小伙伴可以参考下

">

前言

和网络 IO 一样,文件读写同样是一个费事的操作。

默认情况下,Python 使用的是系统的阻塞读写。这意味着在 asyncio 中如果调用了f = file('xx')

f.read()

会阻塞事件循环。

本篇简述如何用 asyncio.Future 对象来封装文件的异步读写。

代码在 GitHub。目前仅支持 Linux。

阻塞和非阻塞

首先需要将文件的读写改为非阻塞的形式。在非阻塞情况下,每次调用 read 都会立即返回,如果返回值为空,则意味着文件操作还未完成,反之则是读取的文件内容。

阻塞和非阻塞的切换与操作系统有关,所以本篇暂时只写了 Linux 版本。如果有过 Unix 系统编程经验,会发现 Python 的操作是类似的。flag = fcntl.fcntl(self.fd, fcntl.F_GETFL)

if fcntl.fcntl(self.fd, fcntl.F_SETFL, flag | os.O_NONBLOCK) != 0:

raise OSError()

Future 对象

Future 对象类似 Javascript 中的 Promise 对象。它是一个占位符,其值会在将来被计算出来。我们可以使用

result = await future

在 future 得到值之后返回。而使用

future.set_result(xxx)

就可以设置 future 的值,也意味着 future 可以被返回了。await 操作符会自动调用 future.result() 来得到值。

loop.call_soon

通过 loop.call_soon 方法可以将一个函数插入到事件循环中。

至此,我们的异步文件读写思路也就出来了。通过 loop.call_soon 调用非阻塞读写文件的函数。若一次文件读写没有完成,则计算剩余所学读写的字节数,并再次插入事件循环直至读写完毕。

可以发现其就是把传统 Unix 编程里,非阻塞文件读写的 while 循环换成了 asyncio 的事件循环。

下面是这一过程的示意代码。def read_step(self, future, n, total):

res = self.fd.read(n)

if res is None:

self.loop.call_soon(self.read_step, future, n, total)

return

if not res: # EOF

future.set_result(bytes(self.rbuffer))

return

self.rbuffer.extend(res)

self.loop.call_soon(self.read_step, future, self.BLOCK_SIZE, total)

def read(self, n=-1):

future = asyncio.Future(loop=self.loop)

self.rbuffer.clear()

self.loop.call_soon(self.read_step, future, min(self.BLOCK_SIZE, n), n)

return future

转载地址:http://ngqsx.baihongyu.com/

你可能感兴趣的文章
沙盒目录介绍
查看>>
260. Single Number III
查看>>
Hadoop生态圈-Kafka的完全分布式部署
查看>>
css的border的solid
查看>>
[MODx] Build a CMP (Custom manager page) using MIGX in MODX 2.3 -- 1
查看>>
jQuery自动完成点击html元素
查看>>
[算法]基于分区最近点算法的二维平面
查看>>
webpack多页应用架构系列(七):开发环境、生产环境傻傻分不清楚?
查看>>
笨办法学C 练习1:启用编译器
查看>>
树的总结--树的性质(树的深度) leetcode
查看>>
nagios短信报警(飞信fetion20080522004-linrh4)
查看>>
【Android游戏开发之六】在SurfaceView中添加组件!!!!并且相互交互数据!!!!...
查看>>
linux 将大文件分成小文件
查看>>
CCNA- 距离矢量路由协议学习
查看>>
企业实践用户邮箱导入/导出(第2部分)
查看>>
如何学习Linux命令-初级篇
查看>>
从Oracle Public Yum为Oracle Linux建立本地的Yum源
查看>>
在 SELECT 查询中使用表表达式
查看>>
静态路由和默认路由
查看>>
关于阿里开发者招聘节 |这5道笔试真题 你会吗!???
查看>>