max*_*max 6 python io python-3.x
如何以非阻塞模式读取二进制文件或文本文件的内容?
对于二进制文件:当我open(filename, mode='rb'),我得到一个实例io.BufferedReader.文件堡垒io.BufferedReader.read 说:
读取和返回大小字节,或者如果未给出大小或为负,则直到EOF或读取调用将在非阻塞模式下阻塞.
显然,直截了当open(filename, 'rb').read()是阻塞模式.令我惊讶的是,我无法在io如何选择非阻塞模式的文档中找到任何解释.
对于文本文件:当我open(filename, mode='rt'),我得到io.TextIOWrapper.我假设相关的文档是read基类中的文档io.TextIOBase; 并根据这些文档,似乎没有办法做到无阻塞阅读所有:
从流中读取并返回最多大小字符作为单个str.如果大小为负或无,则读取直到EOF.
emo*_*ris 13
O_NONBLOCK通过设置标志,Python 确实支持非阻塞读取,至少在 Unix 类型系统上是这样。在 Python 3.5+ 中,有一个os.set_blocking()函数可以让这变得更容易:
import os
f = open(filename, 'rb')
os.set_blocking(f.fileno(), False)
f.read() # This will be non-blocking.
Run Code Online (Sandbox Code Playgroud)
然而,正如zvone 的回答所述,这不一定适用于实际的磁盘文件。但这不是 Python 的问题,而是操作系统的限制。正如 Linux open(2) 手册页所述:
请注意,此标志对常规文件和块设备没有影响;也就是说,当需要设备活动时,I/O 操作将(短暂)阻塞,无论是否设置了 O_NONBLOCK。
但它确实表明这可能会在未来实施:
由于 O_NONBLOCK 语义最终可能会被实现,因此在为常规文件和块设备指定此标志时,应用程序不应依赖于阻塞行为。
文件操作正在阻塞.没有非阻塞模式.
但是您可以创建一个在后台读取文件的线程.在Python 3中,concurrent.futures模块在这里很有用.
from concurrent.futures import ThreadPoolExecutor
def read_file(filename):
with open(filename, 'rb') as f:
return f.read()
executor = concurrent.futures.ThreadPoolExecutor(1)
future_file = executor.submit(read_file, 'C:\\Temp\\mocky.py')
# continue with other work
# later:
if future_file.done():
file_contents = future_file.result()
Run Code Online (Sandbox Code Playgroud)
或者,如果您需要在操作完成时调用回调:
def on_file_reading_finished(future_file):
print(future_file.result())
future_file = executor.submit(read_file, 'C:\\Temp\\mocky.py')
future_file.add_done_callback(on_file_reading_finished)
# continue with other code while the file is loading...
Run Code Online (Sandbox Code Playgroud)
我建议使用aiofiles - 一个用于在 asyncio 应用程序中处理本地磁盘文件的库。
f = yield from aiofiles.open('filename', mode='r')
try:
contents = yield from f.read()
finally:
yield from f.close()
print(contents)
'My file contents'
Run Code Online (Sandbox Code Playgroud)
异步风格版本
async def read_without_blocking():
f = await aiofiles.open('filename', mode='r')
try:
contents = await f.read()
finally:
await f.close()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3204 次 |
| 最近记录: |