Python sys.stdin.read(max)阻塞直到读取最大值(如果max> = 0),阻塞直到EOF else,但select表示有数据要读取

Ale*_*eal 10 python file-io file

我的问题是:

select表示有数据需要读取,我想读取其中的任何内容,我不想等待max数量存在.如果max<= 0则读取等待直到遇到EOF,如果max> 0读取块直到max可以读取字节.

我不想要这个,我想阅读任何数量的选择把它放在"准备阅读"列表中.read(1)不实用,因为这将涉及大量的读取调用.但它不能阻止.

有没有办法在select返回时找出缓冲区中存在的数量(如果它返回表示可以读取某些内容而不是超时)并读取该数量?有没有办法max像套接字一样使用?它尽可能多地读取,然后返回?

解决方案可能是将文件置于非阻塞模式以进行读取?我不确定,我没想到这个"直到EOF"的行为.

我会继续阅读和尝试,但我只花了30分钟左右而且没有接近,这就是我呼吁你的原因.

注意

有很多问题询问如何使recv等待一定量的输入,并使事情阻塞直到达到最大值,我不是在寻找这个.我的问题阻塞.

附录

setblocking(False)没有用,我现在正在阅读如何在阅读期间使其无阻塞.我对文件给予了希望:

stdin.read Found at: sys
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.
Run Code Online (Sandbox Code Playgroud)

增编二

似乎read(0)实际上读取0,这没什么,这导致无限循环,这很有趣!

对不起,我实际上并没有尝试过0看起来,我开始用4096(认为它会读到那里的任何东西......)尝试没有参数,但不是0.

我想知道read(0)会有什么用?

增编三

我现在遇到select问题(我试过把read(1)作为解决方案)这是实际的代码:

def getInput(self):
    log.log(log.INFO,"GetInput","Select")
    readsReady = select.select((sys.stdin,),(),(),1)[0]
    if len(readsReady) == 0:
        #timed out
        log.log(log.INFO,"GetInput","Select timed out")
        if not self.toClose:
            self.handler.post("GetInput")
        else:
            threads.getCurrentThread().removeAllHandlers()
    else:
        #OPTIMISED FOR READING 1
        #log.log(log.INFO,"GetInput","Reading")
        data = sys.stdin.read(1)
        log.log(log.INFO,"GetInput","Read: "+data)

        if data == "\n":
            self.onInputHandler.post("OnInput",self.buffer)
            self.buffer=""
        else:
            self.buffer+=data
        self.handler.post("GetInput")
Run Code Online (Sandbox Code Playgroud)

以下输出中几乎没有与此无关的东西,它们是"Hello world!".几乎立刻就出现了,并且"TEST!" 大约5秒钟."你好"是我键入的内容,输入,"k"是我后来输入的内容,输入后我按下输入一次.

输出:

0.0147    Verbose        1   SocketReader                        Created reader
0.0156    Verbose        2   SocketWriter                        Created writer
0.0260    Information    0   SocketReadWriter                    Created and ready for: ('localhost', 8294)
0.0268    Information    3   GetInput                            Select
Hello World!
1.0281    Information    3   GetInput                            Select timed out
1.0584    Information    3   GetInput                            Select
2.0593    Information    3   GetInput                            Select timed out
2.0896    Information    3   GetInput                            Select
3.0900    Information    3   GetInput                            Select timed out
3.1203    Information    3   GetInput                            Select
4.1215    Information    3   GetInput                            Select timed out
4.1519    Information    3   GetInput                            Select
TEST!
5.1524    Information    3   GetInput                            Select timed out
5.1828    Information    3   GetInput                            Select
hello
6.1467    Information    3   GetInput                            Read: h
6.1770    Information    3   GetInput                            Select
7.1782    Information    3   GetInput                            Select timed out
7.2086    Information    3   GetInput                            Select
8.2098    Information    3   GetInput                            Select timed out
8.2401    Information    3   GetInput                            Select
9.2414    Information    3   GetInput                            Select timed out
9.2717    Information    3   GetInput                            Select
10.2723   Information    3   GetInput                            Select timed out
10.3026   Information    3   GetInput                            Select
k
10.7939   Information    3   GetInput                            Read: e
10.8243   Information    3   GetInput                            Select
10.8245   Information    3   GetInput                            Read: l
10.8547   Information    3   GetInput                            Select
10.8549   Information    3   GetInput                            Read: l
10.8851   Information    3   GetInput                            Select
10.8853   Information    3   GetInput                            Read: o
10.9155   Information    3   GetInput                            Select
10.9157   Information    3   GetInput                            Read: 

10.9459   Information    3   GetInput                            Select
10.9461   Information    3   GetInput                            Read: k
10.9763   Information    3   GetInput                            Select
You said: hello
11.9775   Information    3   GetInput                            Select timed out
12.0123   Information    3   GetInput                            Select
13.0133   Information    3   GetInput                            Select timed out
13.0437   Information    3   GetInput                            Select
^C13.3985   Verbose        2   Threads                             Thread: 2 has ended
14.0442   Information    3   GetInput                            Select timed out
14.0746   Information    3   GetInput                            Select
14.3622   Verbose        1   Threads                             Thread: 1 has ended
15.0758   Information    3   GetInput                            Select timed out
15.1363   Information    3   GetInput                            Select
16.1373   Information    3   GetInput                            Select timed out
16.1677   Verbose        3   Threads                             Thread: 3 has ended
Run Code Online (Sandbox Code Playgroud)

这在这里更容易看到:http://pastebin.com/raw.php?i = H6UHHmy8

有什么奇怪的?

它读取hello的"h",但是在k发生之前不读取"hello \n",如果有意义的话,它总是在1个换行符后面1个字母.

多次调用选择会导致问题吗?(在另一个线程中,套接字阅读器也使用select)

日志的格式为:

*自程序启动以来的时间

*日志级别

*线程ID(运行线程中唯一)

*日志标签

*记录消息

Handler类的功能

允许线程安全地相互发布消息,处理程序检查队列(并且任何预定的事件发生在某个时间,如TEST,这发生在不同的线程上,不用担心),"GetInput"的帖子调度另一个GetInput调用,将其放在队列的后面."OnInput"消息被传递给另一个线程的处理程序,我想要处理输入.

我这样做是因为它提供了一种处理线程的好方法,并且意味着我有一个很好的可重用代码(比如SocketReadWriter),我希望这不会导致对我的线程模型的批评,但它确实有效.问题在于我尝试获取用户输入.

你还可以看到当我按ctrl + c关闭事物时,这就是toClose的功能.当选择超时时,如果它应该关闭,它将会.线程在没有剩余处理程序时结束(处理程序仅在线程运行的函数返回后接管,此函数可能创建一个具有成员处理程序的类,因此当构造函数返回时,函数返回,有一个处理程序保持类活着)

解决

def getInput(self):
    log.log(log.INFO,"GetInput","Select")
    if sys.stdin.closed:
        readsReady = []
    else:
        readsReady = select.select((sys.stdin,),(),(),1)[0]
    if len(readsReady) == 0:
        #timed out
        log.log(log.INFO,"GetInput","Select timed out")
        if not self.toClose:
            self.handler.post("GetInput")
        else:
            threads.getCurrentThread().removeAllHandlers()
    else:
        data = sys.stdin.readline()
        if len(data) == 0:
            log.log(log.WARN,"GetInput","No data was returned indicating the file was closed")
            self.handler.post("GetInput") #if this is a close event, the next
            #timeout will deal with it
            return
        if data[-1] == "\n":
            data = data[:-1]
        log.log(log.INFO,"GetInput","Read: "+data)
        self.onInputHandler.post("OnInput",data)
        #if data == "\n":
        #   self.onInputHandler.post("OnInput",self.buffer)
        #   self.buffer=""
        #else:
        #   self.buffer+=data
        self.handler.post("GetInput")

def onClose(self):
    #log.log(log.WARN,"Input: OnClose","Called")
    self.toClose = True
    sys.stdin.close()
Run Code Online (Sandbox Code Playgroud)

zch*_*zch 6

os模块中,有一个os.read功能允许对文件描述符的读取进行较低级别的控制。只要没有至少一个字节可供读取,它就是非阻塞的。

os.read(fd, n)
Run Code Online (Sandbox Code Playgroud)

从文件描述符fd读取最多n个字节。返回包含读取的字节的字符串。如果已到达fd引用的文件末尾,则返回一个空字符串。

可用性:Unix,Windows。

注意:此函数用于低级I / O,并且必须应用于os.open()或返回的文件描述符pipe()。读取由返回一个“文件对象”的内置功能open()popen()fdopen()sys.stdin使用其read()readline()方法。