Rospy使用json.load()读取文件时触发JSONDecodeError问题求助
问题根因
你的报错和ROS回调机制无关,ROS订阅者回调中完全允许执行文件读写逻辑,问题出在Python文件打开模式的错误使用:
你使用w+模式打开JSON文件,该模式的核心特性是打开文件时会直接清空文件所有内容,哪怕你预先在文件中写入了[],只要执行open(DB, 'w+')操作,文件内容会立刻被清空,json.load读取到的是空字符串,自然触发JSONDecodeError: Expecting value: line 1 column 1 (char 0)报错。
另外你的代码还存在隐藏问题:就算读取成功,读完后文件指针位于文件末尾,直接执行json.dump会把新的JSON数组追加到原有内容后面,最终整个文件会变成非合法JSON格式,后续读取依然会报错。
修复后的正确实现
推荐使用Python上下文管理器with处理文件IO,自动处理文件关闭逻辑,避免资源泄漏:
import json import os DB = '/home/path/data.json' def callback(msg): # 此处data是你从ROS消息中解析出的待存储数据 data = { # 示例字段,根据你的实际消息格式修改 "timestamp": msg.header.stamp.to_sec(), "data": msg.data } # 步骤1:文件不存在/为空时,先初始化空JSON数组 if not os.path.exists(DB) or os.path.getsize(DB) == 0: with open(DB, 'w', encoding='utf-8') as f: json.dump([], f) # 步骤2:读取现有JSON数组 with open(DB, 'r', encoding='utf-8') as f: json_array = json.load(f) # 步骤3:追加新数据 json_array.append(data) # 步骤4:覆盖写入更新后的数组 with open(DB, 'w', encoding='utf-8') as f: json.dump(json_array, f, indent=2, ensure_ascii=False)
高频回调场景优化建议
如果你的ROS话题发布频率很高(比如大于1Hz),每次回调都全量读写磁盘会带来不必要的性能开销,推荐两种优化方案:
- 内存缓存方案:在节点全局维护一个Python列表存储数据,监听ROS节点关闭信号,节点退出前一次性把所有数据写入JSON文件
- JSON Lines方案:每次回调只向文件追加一行单条JSON数据,不需要每次读取全量文件,后续处理时按行解析即可,读写性能远高于全量JSON读写
内容的提问来源于stack exchange,提问作者Jack Vision
相关产品推荐
相关产品推荐

