如何避免“ValueError:未找到分隔符,并且块超出限制”

Ere*_*evi 6 python-3.x python-asyncio

我有一个按以下方式使用 asyncio 的服务器:

proc = await asyncio.subprocess.create_subprocess_exec(
    command,
    stdout=asyncio.subprocess.PIPE, 
    stderr=asyncio.subprocess.STDOUT)

async for line in proc.stdout:
    line = line.decode('utf-8').strip()
    print(line)
Run Code Online (Sandbox Code Playgroud)

问题是,如果proc.stdout包含太长的行,我会在for语句行中收到错误:

ValueError: Separator is not found, and chunk exceed the limit
Run Code Online (Sandbox Code Playgroud)

如何检测如此长的线路以提前避免此错误?

Mik*_*mov 8

正如文档所说:

该参数为和 的包装器 limit设置缓冲区限制(如果传递给 stdout 和 stderr 参数)。StreamReaderProcess.stdoutProcess.stderrsubprocess.PIPE

似乎正是我们所需要的。

默认限制似乎是64 KiB,您可以尝试更高的值:

proc = await asyncio.subprocess.create_subprocess_exec(
    command,
    limit = 1024 * 128,  # 128 KiB
    stdout=asyncio.subprocess.PIPE, 
    stderr=asyncio.subprocess.STDOUT)
Run Code Online (Sandbox Code Playgroud)

更新:

我只想截断/忽略太长的行。这可能吗?

您可以抑制长行中的错误,然后继续。以下代码(在 Windows 上测试)显示了这个想法:

import asyncio


async def main():
    proc = await asyncio.subprocess.create_subprocess_exec(
        *[
            'wget', 
            '--help'
        ],
        limit = 20,
        stdout=asyncio.subprocess.PIPE, 
        stderr=asyncio.subprocess.STDOUT)

    while True:
        try:
            async for line in proc.stdout:
                line = line.decode('utf-8').strip()
                print(line)
        except ValueError:
            continue
        else:
            break


loop = asyncio.ProactorEventLoop()
asyncio.set_event_loop(loop)
loop.run_until_complete(main())
Run Code Online (Sandbox Code Playgroud)