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

Go语言解析JSON文件:如何仅提取items数组

嘿,这个需求其实挺常见的——不用解析整个JSON结构,只抓items数组,既能省内存又能提高效率,尤其是处理大文件的时候。我给你两种实用的实现方式,都是Go生态里常用的:

方法1:用json.RawMessage做部分解析(适合中小JSON文件)

这种方法最简单,只需要定义一个只包含items字段的结构体,Go的encoding/json库会自动忽略其他不关心的字段。如果知道items里元素的具体结构,还可以直接把数组类型定义成对应的结构体;如果不确定结构,先用json.RawMessage存着,之后再按需解析。

示例代码:

package main

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

// 只定义我们需要的items字段,其他字段会被自动忽略
type PartialData struct {
	// 如果知道items元素的结构,直接替换成 []Item
	Items []json.RawMessage `json:"items"`
}

// 假设items里的元素是这种结构(根据你的实际情况调整)
type Item struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
	Desc string `json:"description,omitempty"`
}

func main() {
	// 读取JSON文件内容
	fileContent, err := os.ReadFile("your_file.json")
	if err != nil {
		fmt.Printf("读取文件出错: %v\n", err)
		return
	}

	var data PartialData
	// 解析JSON到结构体,只提取items字段
	if err := json.Unmarshal(fileContent, &data); err != nil {
		fmt.Printf("解析JSON出错: %v\n", err)
		return
	}

	// 如果需要把RawMessage解析成具体的Item结构体
	var parsedItems []Item
	for _, rawItem := range data.Items {
		var item Item
		if err := json.Unmarshal(rawItem, &item); err != nil {
			fmt.Printf("解析单个item出错: %v\n", err)
			continue
		}
		parsedItems = append(parsedItems, item)
	}

	fmt.Println("提取到的items数组:", parsedItems)
}

方法2:流式解析(适合超大JSON文件)

如果你的JSON文件特别大(比如几百MB甚至几个G),一次性加载到内存里会很吃力,这时候用json.Decoder的流式解析就很合适——它会逐token读取JSON,找到items字段后直接解析数组,其他字段直接跳过,完全不用加载整个文件到内存。

示例代码:

package main

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

// 同样,根据你的实际情况定义Item结构
type Item struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
}

func main() {
	file, err := os.Open("large_file.json")
	if err != nil {
		fmt.Printf("打开文件出错: %v\n", err)
		return
	}
	defer file.Close()

	decoder := json.NewDecoder(file)

	// 先跳过JSON开头的大括号 {
	token, err := decoder.Token()
	if err != nil {
		fmt.Printf("读取起始token出错: %v\n", err)
		return
	}
	if delim, ok := token.(json.Delim); !ok || delim != '{' {
		fmt.Println("JSON格式错误,不是对象类型")
		return
	}

	// 遍历JSON对象的所有键值对
	for decoder.More() {
		key, err := decoder.Token()
		if err != nil {
			fmt.Printf("读取字段key出错: %v\n", err)
			return
		}

		// 找到我们要的items字段
		if keyStr, ok := key.(string); ok && keyStr == "items" {
			var items []Item
			// 直接解析items数组
			if err := decoder.Decode(&items); err != nil {
				fmt.Printf("解析items数组出错: %v\n", err)
				return
			}
			fmt.Println("提取到的items数组:", items)
			break // 找到目标后直接退出,不用处理其他字段
		} else {
			// 跳过不关心的字段
			if err := decoder.Skip(); err != nil {
				fmt.Printf("跳过无关字段出错: %v\n", err)
				return
			}
		}
	}
}

两种方法的选择建议

  • 如果JSON文件不大(几十MB以内),优先用方法1,代码简单易维护;
  • 如果是超大文件,或者内存资源紧张,用方法2的流式解析更高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:10:12