异步文件 I/O 支持

Asynchronous file I/O support

AnyIO 提供了阻塞文件操作的异步包装器。这些包装器在工作线程中运行阻塞操作。

示例:

from anyio import open_file, run


async def main():
    async with await open_file('/some/path/somewhere') as f:
        contents = await f.read()
        print(contents)

run(main)

这些包装器还支持按行异步迭代文件内容,就像标准文件对象支持同步迭代一样:

from anyio import open_file, run


async def main():
    async with await open_file('/some/path/somewhere') as f:
        async for line in f:
            print(line, end='')

run(main)

要将现有的打开文件对象包装为异步文件,可以使用 wrap_file():

from anyio import wrap_file, run


async def main():
    with open('/some/path/somewhere') as f:
        async for line in wrap_file(f):
            print(line, end='')

run(main)

备注

关闭包装器时,也会关闭底层的同步文件对象。

参见

文件流

异步路径操作

Asynchronous path operations

AnyIO 提供了 pathlib.Path 类的异步版本。它与原版有一些不同之处:

  • 执行磁盘 I/O 操作的方法(如 read_bytes())会在工作线程中运行,因此需要使用 await

  • glob() 这样的函数返回一个异步迭代器,该迭代器生成异步的 Path 对象

  • 正常返回 pathlib.Path 对象的属性和方法,现在返回 Path 对象

  • Python 3.10 API 中的方法和属性在所有版本中均可用

  • 不支持作为上下文管理器使用,因为在 pathlib 中已被弃用

例如,创建一个包含二进制内容的文件可以这样做:

from anyio import Path, run


async def main():
    path = Path('/foo/bar')
    await path.write_bytes(b'hello, world')

run(main)

异步迭代目录内容可以按如下方式进行:

from anyio import Path, run


async def main():
    # 打印目录 /foo/bar 中每个文件的内容(假定是文本文件)
    dir_path = Path('/foo/bar')
    async for path in dir_path.iterdir():
        if await path.is_file():
            print(await path.read_text())
            print('---------------------')

run(main)