Python读取流

 yangjiao1985 发布于 2022-12-18 20:35

我需要一种非常便宜的方法来读取Python中没有终止字符串(流)的缓冲区.这就是我所拥有的,但它耗费了大量的CPU时间和精力.因为它经常"尝试和捕捉".我真的需要一种新的方法.

这是我的代码的简化工作版本:

#! /usr/bin/env/ python
import fcntl, os, sys

if __name__ == "__main__":
    f = open("/dev/urandom", "r")
    fd = f.fileno()
    fl = fcntl.fcntl(fd, fcntl.F_GETFL)
    fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)

    ready = False
    line = ""
    while True:
        try:
            char = f.read()
            if char == '\r':
                continue
            elif char = '\n':
                ready = True
            else:
                line += char
        except:
            continue
        if ready:
            print line

不要在终端中运行它.这只是为了说明."urandom"将破坏你的终端,因为它会吐出很多随机字符,终端模拟器无论解释什么(可以改变你当前的shell设置,标题等).我正在读取通过usb连接的gps.

问题:这可以使用100%的CPU使用率.我试过这个:

#! /usr/bin/env/ python
import fcntl, os, sys

if __name__ == "__main__":
    f = open("/dev/urandom", "r")
    fd = f.fileno()
    fl = fcntl.fcntl(fd, fcntl.F_GETFL)
    fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)

    for line in f.readlines():
        print line

但是,我明白了IOError: [Errno 11] Resource temporarily unavailable.我曾尝试过使用Popen其他东西.我很茫然.有人可以提供解决方案(请解释一切,因为我本身不是专业人士).此外,我应该注意这是针对Unix(特别是Linux,但它必须可以在所有版本的Linux上移植).

2 个回答
  • 简单的解决方案是最好的:

    with open('/dev/urandom', 'r') as f:
        for line in f:
            print line.encode('hex')  # Don't mess up my terminal
    

    或者,或者

    with open('/dev/urandom', 'r') as f:
        for line in iter(f.readline, ''):
            print line.encode('hex')  # Don't mess up my terminal
    

    笔记:

    将文件描述符保留在阻止模式下,以便在没有可用数据时,操作系统可以阻止您的进程(并节省CPU时间)。

    在循环中使用迭代器很重要。考虑一下for line in f.readlines():f.readlines()读取所有数据,将所有数据放入列表中,然后返回该列表。由于我们拥有无限的数据,f.readlines()因此永远不会成功返回。相反,f返回一个迭代器-它仅获取满足下一个循环迭代所需的数据(而对于性能缓冲区则仅获取更多数据)。

    第一个版本会预先读取并缓冲足够的数据以打印多行。第二个版本立即返回每一行。如果您最关心的是节省CPU,请使用第一个版本。如果您主要关注交互式响应时间,请使用第二个。

    示范:

    $ python x.py  | head -2l
    eb99f1b3bf74eead42750c63cb7c16160fa7e21c94b176dc6fd2d6796a1428dc8c5d15f13e3c1d5969cb59317eaba37a97f4719bb3de87919009da013fa06ae738408478bc15c750850744a4edcc27d155749d840680bf3a827aafbe9be84e7c8e2fe5785d2305cbedd76454573ca9261ac9a480f71242baa94e8d4bdf761705a6a0fea1ba2b1502066b2538a62776e9165043e5b7337d45773d009fd06d15ca0d9b51af499c1c9d7684472272a7361751d220848874215bc494456b08910e9815fc533d3545129aad4f3f126dc5341266ca4b85ea949794cacaf16409bcd02263b08613190b3f69caa68a47758345dafb10121cfe6ed6c8098142682aef47d1080bd2e218b571824bf2fa5d0bb5297278be8a9a2f55b554631c99e5f1d9040c5bc2bde9a40c8b6e95fc47be6ea9235243582f2367893d15a1494f732d0346ec6184a366f8035aef9141c638128444b1549a64937697b1a170e648d20f336e352076893fa7265c8fa0f4e2207e87410e53b43a51aa146ac6c2decf274a45a58c4e442aececf28879a3e0b4a1278eac7a4f969b3f74e2f2a2064a55ff112c4c49092366dbaa125703962ec5083d09cdb750c0e1dbe34cadda66709f98ff63faccf0045993137bfaca949686bc395bbafb7cf9b5b3475a0c91bdea8cec4e9ac1a9c96e0b81c1c5f242ae72cdea4c073db0351322f9da31203ea34d1b6f298128435797f4846a53b0733069060680dbc2b44c662c4b685ced5419b65c01df41cc2dd9877dc2a97a965174d508a3c9275d8aee7f2991bbb06ca7e0010b0e5b9468aed12f5d2c9a65091223547b8655211df435ffbf24768d48c7e7cf3cb7225f2c116e94a8602078f2b34dab6852f57708e760f88f4085ec7dade19ed558a539f830adea1b81f46303789224802f1f090ec0ff59e291246f1287672b0035df07c359d2ada48e674622f61c0f456c36d130fb6cf7f529e7c4dfceccc594ba5e812a3250e022eca9576a5a8b31c0be13969841d5a4d52b10a7dc8ddd1cac279500cb66e3b244e7d1e042249fd8adf2a90fa8bee74378d79a3d55c6fcf6cc19aa85ffb078dba23ca88ea6810d4a1c5d98b3b33e68ddd41c881df167c36ab2e1b081849781e08e3a026fbd3755acf9f215e0402cbf1a021300f5c883f86a05d467479172109a8f20f93c8c255915a264463eb113c3e8d07d0cec31aa8c0f978a0e7e65c142e85383befd6679c69edd2c56599f15580bbb356d98cfdf012dbc6d1dd6c0dbcfe6f8235d3d5c015fb94d8cc29afdf5d69e33d0e5078d651782546bc2acccab9f35e595f0951a139526ae5651a3ebbec353e99f9ddd1615ed25529500dabe8bf6f12ee6b21a437caca12a6d9688986d94fb7c103dca1572350900e56276b857630a
    9d024ef4454dcd5e35dd605a2d49c26ce44fae87ab33e7a158d328521c7d77969908ec5b67f01bf8e2c330dcb70b5f3def8e6d4b010c6d31e4cbe7478657782f10b6fc2d77e8ff7a2f1e590827827e1037b33b0a
    Traceback (most recent call last):
      File "x.py", line 4, in <module>
        print line.encode('hex')  # Don't mess up my terminal
    IOError: [Errno 32] Broken pipe
    

    2022-12-18 20:40 回答
  • 您需要将缓冲模式设置为打开文件流时要读取的块的大小.从python文档:

    io.open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True)
    

    " buffering是一个可选的整数,用于设置缓冲策略.传递0以切换缓冲关闭(仅允许在二进制模式下),1传递选择行缓冲(仅在文本模式下可用),并且整数> 1表示大小一个固定大小的块缓冲区."

    您还希望在while循环中使用readable()方法,以避免不必要的资源消耗.

    但是,我建议你使用缓冲流,如io.BytesIOio.BufferedReader

    更多信息在文档中.

    2022-12-18 20:40 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有