Python从命名管道/FIFO读取JSON

问题描述

我正在尝试从 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”。奇怪的是,我可以成功加载第一行并将其打印为Python字典,如下面的日志所示,但在第二行我观察到以下错误

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)

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

编辑:添加 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");
        }
    }
}

解决方法

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...