Golang中如何压缩JSON数据

Golang中如何压缩JSON数据 我正在学习Go语言,并尝试找出如何压缩小的JSON片段。目前我的代码如下:

// return a minified JSON input string
// return an error encountered during minifiying or reading minified bytes
func minify(jsonB []byte) ([]byte, error) {

	var buff *bytes.Buffer = new(bytes.Buffer)
	errCompact := json.Compact(buff, jsonB)
	if errCompact != nil {
		newErr := fmt.Errorf("failure encountered compacting json := %v", errCompact)
		return []byte{}, newErr
	}

	b, err := ioutil.ReadAll(buff)
	if err != nil {
		readErr := fmt.Errorf("read buffer error encountered := %v", err)
		return []byte{}, readErr
	}

	return b, nil
}

在Go Playground上包含了一个测试桩,链接在这里

我这样做方向对吗?还是有更简单的方法?


更多关于Golang中如何压缩JSON数据的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中如何压缩JSON数据的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go中压缩JSON数据(移除空格和换行)使用json.Compact是正确的做法。你的代码方向正确,但可以进一步简化。以下是优化后的实现:

func minify(jsonB []byte) ([]byte, error) {
    var buff bytes.Buffer
    if err := json.Compact(&buff, jsonB); err != nil {
        return nil, fmt.Errorf("failure encountered compacting json: %w", err)
    }
    return buff.Bytes(), nil
}

关键改进点:

  1. 直接使用bytes.Buffer值而非指针
  2. 移除冗余的ioutil.ReadAll调用,直接使用buff.Bytes()
  3. 使用%w包装错误以保留原始错误链
  4. 错误时返回nil而非空切片

更简洁的单行版本:

func minify(jsonB []byte) ([]byte, error) {
    var b bytes.Buffer
    return b.Bytes(), json.Compact(&b, jsonB)
}

测试示例:

func main() {
    input := []byte(`{
        "name": "John",
        "age": 30,
        "city": "New York"
    }`)
    
    minified, err := minify(input)
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Printf("Original: %d bytes\n", len(input))
    fmt.Printf("Minified: %d bytes\n", len(minified))
    fmt.Printf("Result: %s\n", minified)
    // 输出: {"name":"John","age":30,"city":"New York"}
}

对于需要压缩而非仅移除空格的情况(如gzip压缩),可以使用compress/gzip包:

import "compress/gzip"

func compressJSON(jsonB []byte) ([]byte, error) {
    var b bytes.Buffer
    gz := gzip.NewWriter(&b)
    if _, err := gz.Write(jsonB); err != nil {
        return nil, err
    }
    if err := gz.Close(); err != nil {
        return nil, err
    }
    return b.Bytes(), nil
}

你的实现基本正确,简化后更符合Go的惯用法。

回到顶部