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

Golang实现JSON键值对追加与Map导出问题求助

解决Go中键值对JSON文件的读写与追加问题

要实现键值对形式的JSON文件({"key": value, ...}),核心是先读取现有数据合并,再覆盖写入,而不是直接追加字符串(这会导致JSON格式破坏,出现[{...}][{...}]这类无效结构)。以下是具体实现方案:

核心思路

JSON对象是单一的顶层结构,无法通过直接追加字符串来添加新键值对。正确流程是:

  1. 读取现有db.json内容,若文件不存在则初始化空Map
  2. 将JSON解析为Go的map[string]interface{}(或特定类型Map)
  3. 向Map中添加/更新键值对
  4. 将更新后的Map重新序列化为JSON,覆盖写入文件

完整代码实现

package main

import (
	"encoding/json"
	"os"
)

// loadDB 读取db.json并解析为Map,文件不存在则返回空Map
func loadDB(path string) (map[string]interface{}, error) {
	file, err := os.Open(path)
	if err != nil {
		if os.IsNotExist(err) {
			return make(map[string]interface{}), nil
		}
		return nil, err
	}
	defer file.Close()

	var db map[string]interface{}
	if err := json.NewDecoder(file).Decode(&db); err != nil {
		return nil, err
	}
	return db, nil
}

// saveDB 将Map序列化为JSON并写入db.json
func saveDB(path string, db map[string]interface{}) error {
	// 创建文件(覆盖原有内容)
	file, err := os.Create(path)
	if err != nil {
		return err
	}
	defer file.Close()

	// 格式化输出JSON(可选,便于阅读)
	encoder := json.NewEncoder(file)
	encoder.SetIndent("", "  ")
	return encoder.Encode(db)
}

// addKV 向db.json中添加/更新键值对
func addKV(path string, key string, value interface{}) error {
	db, err := loadDB(path)
	if err != nil {
		return err
	}
	db[key] = value
	return saveDB(path, db)
}

func main() {
	// 示例:添加两个键值对
	if err := addKV("db.json", "username", "Arsh Ergon"); err != nil {
		panic(err)
	}
	if err := addKV("db.json", "role", "developer"); err != nil {
		panic(err)
	}
}

关键说明

  • 避免直接追加写入:直接用os.O_APPEND模式写入JSON字符串会生成{"a":1}{"b":2}这类无效JSON,无法被正确解析为单个对象。
  • 类型安全优化:如果你的值都是固定类型(比如全是字符串),可以将map[string]interface{}替换为map[string]string,减少类型断言的麻烦。
  • 原子写入(可选):如果需要避免写入失败导致文件损坏,可以先写入临时文件,再替换原文件:
    func saveDB(path string, db map[string]interface{}) error {
        tempPath := path + ".tmp"
        file, err := os.Create(tempPath)
        if err != nil {
            return err
        }
        defer file.Close()
    
        encoder := json.NewEncoder(file)
        encoder.SetIndent("", "  ")
        if err := encoder.Encode(db); err != nil {
            os.Remove(tempPath)
            return err
        }
    
        return os.Rename(tempPath, path)
    }
    

查询与导出Map

读取db.json后直接得到的就是Go的Map结构,可直接用于查询:

db, err := loadDB("db.json")
if err != nil {
    panic(err)
}
// 查询键值
username := db["username"].(string)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 22:10:28