You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何逐行解析JSON对象中B数组的子元素(避免全量加载至内存)

流式解析JSON中指定数组的元素(避免全量加载)

针对你这种外层是对象、其中某个数组包含大量元素的场景,我们可以利用JSON解析器的流式Token读取能力,精准定位到目标数组后逐个解析元素,完全不需要把整个JSON加载到内存里。下面以Go语言的encoding/json包为例,给出具体实现方案:

核心思路

  1. 用json.Decoder逐个读取JSON的Token,跳过外层对象中不需要的键值对(比如你的"A"数组)。
  2. 定位到"B"对应的数组后,循环读取数组内的每个对象,解析一个处理一个,处理完就释放内存,不会堆积大量数据。

具体实现代码

package main

import (
	"encoding/json"
	"fmt"
	"io"
	"os"
)

// 定义B数组中单个元素的结构体,按需调整字段
type BItem struct {
	C string `json:"c"`
	D string `json:"d"`
}

func main() {
	// 打开目标JSON文件(也可以替换为HTTP响应体等其他io.Reader)
	file, err := os.Open("your_data.json")
	if err != nil {
		panic(err)
	}
	defer file.Close()

	decoder := json.NewDecoder(file)

	// 第一步:跳过外层对象的起始标记 '{'
	token, err := decoder.Token()
	if err != nil {
		panic(err)
	}
	if delim, ok := token.(json.Delim); !ok || delim != '{' {
		panic("JSON格式错误,预期外层为对象")
	}

	// 第二步:遍历外层对象的键值对,找到"B"键
	for decoder.More() {
		// 读取当前键名
		keyToken, err := decoder.Token()
		if err != nil {
			panic(err)
		}
		key, ok := keyToken.(string)
		if !ok {
			panic("预期键名为字符串格式")
		}

		if key == "A" {
			// 直接跳过"A"对应的整个数组,不解析内容
			if err := decoder.Skip(); err != nil {
				panic(err)
			}
		} else if key == "B" {
			// 定位到"B"数组,开始逐个解析元素
			token, err := decoder.Token()
			if err != nil {
				panic(err)
			}
			if delim, ok := token.(json.Delim); !ok || delim != '[' {
				panic("B对应的不是数组格式")
			}

			// 循环解析数组中的每个元素
			for decoder.More() {
				var item BItem
				if err := decoder.Decode(&item); err != nil {
					panic(err)
				}
				// 这里写你对单个元素的处理逻辑,比如写入数据库、计算统计值等
				fmt.Printf("处理完成元素:%+v\n", item)
			}

			// 跳过数组的结束标记 ']'
			if _, err := decoder.Token(); err != nil {
				panic(err)
			}
		} else {
			// 遇到其他未知键时,同样跳过对应的值
			if err := decoder.Skip(); err != nil {
				panic(err)
			}
		}
	}

	// 跳过外层对象的结束标记 '}'
	if _, err := decoder.Token(); err != nil {
		panic(err)
	}

	fmt.Println("所有元素处理完成")
}

关键细节说明

  • decoder.Token():用来逐个读取JSON的基础单元(比如大括号、方括号、字符串等),让我们能精准控制解析流程,不浪费内存解析无关内容。
  • decoder.Skip():跳过当前Token对应的整个JSON值(比如整个"A"数组),不需要解析其内部结构,直接跳过,节省内存和时间。
  • decoder.More():判断当前数组或对象中是否还有未处理的元素,用来控制循环的终止时机。
  • 每个BItem解析完成后,会立即进入处理逻辑,处理完该对象就会被垃圾回收机制回收,内存始终只保留当前正在处理的单个元素,彻底解决大JSON的内存过载问题。

内容的提问来源于stack exchange,提问作者Kyle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 06:27:26