Python 从命名管道/FIFO 中读取 JSON

Posted

技术标签:

【中文标题】Python 从命名管道/FIFO 中读取 JSON【英文标题】:Python read JSON from named pipe/FIFO 【发布时间】:2021-01-15 13:51:55 【问题描述】:

我正在尝试从 FIFO 中读取 JSON 数据,如下代码所示:

import os
import errno
import json

FIFO = '/tmp/vision'

try:
    os.mkfifo(FIFO)
except OSError as oe: 
    if oe.errno != errno.EEXIST:
        raise

print("Opening FIFO...")
while True:
    with open(FIFO) as fifo:
        for line in fifo:
            #line = '"humans": []' # WORKS FINE
            print(line)
            perception_output = json.loads(line)
            print(perception_output)
            print(type(perception_output))

我一直在推动 FIFO 单行 JSON 的另一端(C++ 代码)。分隔符是“\n”。奇怪的是,我可以成功加载 first line 并将其打印为 Python 字典,如下面的日志中所示,但在 second line 上我观察到以下错误:

me@pc:~/vision$ python3 brain.py 
Opening FIFO...
 "humans": [ ] 

'humans': []
<class 'dict'>
 "humans": [ ] 

Traceback (most recent call last):
  File "brain1.py", line 19, in <module>
    perception_output = json.loads(line)
  File "/usr/lib/python3.6/json/__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.6/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.6/json/decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

如果我按照评论硬编码“line”变量,我没有问题。可能是什么问题?

编辑:添加 FIFO Writer 的 C++ 代码:

#include <fcntl.h>
#include <iostream>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char* argv[])

    int fd;
    const char * myfifo = "/tmp/vision";
    fd = open(myfifo, O_WRONLY);

    if (fd <= 0) 
        throw std::logic_error("Cannot open FIFO fd");
    

    while (true) 
        std::string json_out = " \"humans\": [ ] \n";
        std::cout << json_out << std::endl;

        if (write(fd, json_out.c_str(), strlen(json_out.c_str()) + 1) < 0) 
        
            throw std::logic_error("Cannot write to FIFO fd");
        
    

【问题讨论】:

请分享MWE @Chandan,我已经添加了作者的 C++ 代码。 好吧,我很笨 :D 谢谢@freakish! 【参考方案1】:

strlen(json_out.c_str()) + 1) 是你的罪魁祸首。你应该做strlen(json_out.c_str()) 或者更好的json_out.length()。每个 c 字符串的最后一个元素是不可见的 \0 字符,然后您将其发送到服务器端。然后\0 char 成为 json 解码器不理解的新行的第一个元素。

【讨论】:

以上是关于Python 从命名管道/FIFO 中读取 JSON的主要内容,如果未能解决你的问题,请参考以下文章

从命名管道读取的 C 不会结束

命名管道和分叉令人头疼

当阅读器断开连接时,命名管道 (FIFO) 数据会去哪里?

为啥这里举例说明在 LINUX 中使用命名管道 -FIFO 的程序会遇到竞争条件?

FIFO管道中的数据丢失?

拦截先进先出