我如何知道要从非阻塞标准输入中读取多少?
How can I tell how much to read from nonblocking stdin?
msvcrt
有一个方便的函数:kbhit()
。 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 个字节:实际的转义字符。
Page Up 发送 \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
这是我的目标 Unix 等价物 (from here):
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
。
我搜索了所有相关文档(tty
、termios
、sys.stdin
、fcntl
、os
),但我不能找不到我要找的东西。
多亏了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
完美运行。
msvcrt
有一个方便的函数:kbhit()
。 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 个字节:实际的转义字符。Page Up 发送
\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
这是我的目标 Unix 等价物 (from here):
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
。
我搜索了所有相关文档(tty
、termios
、sys.stdin
、fcntl
、os
),但我不能找不到我要找的东西。
多亏了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
完美运行。