【问题标题】:Python: clear stdin BufferPython:清除标准输入缓冲区
【发布时间】:2023-04-08 22:47:01
【问题描述】:

这可能是一个菜鸟问题,但我找不到解决方法! 我需要清除python中的stdin缓冲区。

想象一下我正在运行以下 bash 脚本:

i=0
for (( ; ; ))
do
    echo "$i"
    ((i++))
done

像这样从命令行运行:./loop.sh | python myProg.py

在 myProg.py 我希望有如下内容:

count = 100
f = fileinput.input()
while True:
    sleep(2)
    # clear stdin somehow ...
    # and read the most recent 100 lines
    i = 0
    while i < count:
        myBuffer[i] = f.readline()
        if len(myBuffer[i]) > 0:
            i += 1
    print myBuffer

我不认为我可以在它之前阅读所有行,因为它以高速率吐出它们并且如果睡眠(仅用于测试 atm)是几分钟,它似乎很愚蠢......有没有在python中设置标准输入缓冲区大小的方法?或者只是截断/清除它?顺便说一句,我使用 python 2 所以没有 bufsize 参数

我在这里看了How to avoid Python fileinput buffering

有什么 python 方法吗?但我也尝试取消缓冲:https://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe

更新: unbuffer 或 stdbuf 没有运气......

【问题讨论】:

    标签: python file-io buffer stdin


    【解决方案1】:

    以防万一其他人遇到此问题,我进行了广泛的搜索并得出结论,由于内核实现等原因,这是不可能的...

    我写了以下工作来做我想做的事。我创建了两个文件:textFilter.py 和 getLatest.py。基本上你运行 ./loopPrinting.sh | python textFilter.py 并获取最新的 100 行。我有理由确定这是原子且可靠的(尽管如果不是,请告诉我!!!)。它创建 16 个文件并更改计数(类似于我认为的苹果直播)。

    textFilter.py

    import sys
    import os
    import time
    
    def mainLoop(size):
        myBuffer = [0]*size
        count = 0
    
        while True:
            for i in range(size):
                myBuffer[i] = sys.stdin.readline()
    
            f = open('/home/development/textFilter/' + repr(count) + '.dat', 'w')
            f.write(''.join(myBuffer))
            f.close()
    
            f = open('/home/development/textFilter/count.dat~', 'w')
            f.write(repr(count))
            f.flush()
            os.fsync(f.fileno()) 
            f.close()
            time.sleep(0.01)
            os.rename('/home/development/textFilter/count.dat~','/home/development/textFilter/count.dat')
    
            count += 1
            count = count % 16
    
    if __name__ == "__main__":
        try:
            mainLoop(int(sys.argv[1]))
        except Exception:
            mainLoop(100)
    

    getLatest.py

    import sys
    import time
    
    def getData():
        f = open('count.dat', 'r')
        count = f.read()
        f.close()
    
        count = int(count)
        oldCount = count
    
        while oldCount == count:
        time.sleep(0.1)
        f = open('count.dat', 'r')
        count = f.read()
        f.close()
        count = int(count)
    
        f = open(repr(count) + '.dat', 'r')
        data = f.readlines()
        f.close()
    
        for row in data:
        print row,
    
        return 0
    
    if __name__ == "__main__":
        try:
        getData()
        except Exception as inst:
        sys.stderr.write('ERROR')
        sys.stderr.write(inst)
    

    【讨论】: