我怎样才能知道从非阻塞stdin读取多少?

2024-03-29 06:40:11 发布

您现在位置:Python中文网/ 问答频道 /正文

msvcrt有一个方便的函数:^{}。Unix没有:(


我有一个函数_Getch(),比如:

def _Getch():
    if sys.stdin.isatty():
        fd = sys.stdin.fileno()
        old_settings = termios.tcgetattr(fd)
        try:
            tty.setraw(sys.stdin.fileno())
            ch = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
            return ch
    else:
        return sys.stdin.read(1)

只有一个按键。你知道吗

当有人按下时,问题就来了:

  • ESC发送\x1b。这是1字节:实际的转义字符。

  • 向上翻页发送\x1b[H。这是3个字节

  • F2发送\x1b[OQ。这是4个字节。

  • F5发送\x1b[15~。这是5个字节。

看这是怎么回事?一旦读取了ESC,就无法预测以下序列将持续多久。你知道吗

随后的_Getch()调用获得这些字节,但问题是有多少个_Getch()调用。你知道吗


我想定义一个如下函数,它将读取stdin中等待的所有内容,直到什么都没有了:

def _Kbhit():
    y = []
    while msvcrt.kbhit():         # while something is waiting
        y.append(msvcrt.getch())  # get it!
    return y

以下是我的目标(from here)的Unix等价物:

def _Kbhit():
    fd = sys.stdin.fileno()
    fl = fcntl.fcntl(fd, fcntl.F_GETFL)
    fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
    return sys.stdin.read(waiting_buffer_len)  # ?

我只是不知道如何定义waiting_buffer_len。你知道吗

我已经搜索了所有相关的文档(ttytermiossys.stdinfcntlos),但是我找不到我要找的。你知道吗


Tags: 函数readreturn字节defstdinsyswaiting
1条回答
网友
1楼 · 发布于 2024-03-29 06:40:11

多亏了this answer,我做了更多的搜索,而且不直观:

Upon looking at the help documentation for sys.stdin.read, I noticed this:

read(...)

read([size]) -> read at most size bytes, returned as a string.

If the size argument is negative or omitted, read until EOF is reached. Notice that when in non-blocking mode, less data than what was requested may be returned, even if no size parameter was given.

答案是waiting_buffer_len可以是任何长度:

def _Kbhit():
    fd = sys.stdin.fileno()
    fl = fcntl.fcntl(fd, fcntl.F_GETFL)
    fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
    try:
        chars = sys.stdin.read(10)
    except TypeError:
        chars = ""
    finally:
        fcntl.fcntl(fd, fcntl.F_SETFL, fl)
        return chars

效果很好。你知道吗

相关问题 更多 >