Go处理非JSON数据的JSON流方法
时间:2025-10-26 11:09:31 479浏览 收藏
本篇文章给大家分享《Go处理JSON流中的非JSON数据方法》,覆盖了Golang的常见基础知识,其实一个语言的全部知识点一篇文章是不可能说完的,但希望通过这些问题,让读者对自己的掌握程度有一定的认识(B 数),从而弥补自己的不足,更好的掌握它。

本文介绍了一种在Go语言中处理包含非JSON内容的JSON流的方法。当从标准输入或其他来源接收到的JSON数据流中夹杂着非JSON字符串时,标准的`encoding/json`包会报错。本文提供了一种解决方案,通过读取字节切片、裁剪非JSON字符串并使用`json.Unmarshal`进行反序列化,从而有效地解析这类数据流。
在Go语言中处理JSON数据流时,如果数据流中包含非JSON内容,标准的encoding/json包提供的解码器可能会遇到问题。一个常见的场景是,JSON结构体之间穿插着特定的分隔符或标记,例如示例中的"end"字符串。这种情况下,直接使用json.Decoder会因为无法解析非JSON内容而报错。
以下提供一种解决方案,该方案的核心思想是:不使用json.Decoder,而是直接从输入流中读取字节切片,然后手动裁剪掉非JSON部分,最后使用json.Unmarshal将剩余的JSON数据反序列化为Go结构体。
实现步骤
读取字节切片: 使用os.Stdin.Read()从标准输入读取数据到一个字节切片中。需要预先分配足够大的字节切片来容纳可能的数据。
裁剪非JSON内容: 使用bytes.Index()函数查找JSON数据和非JSON内容之间的分隔符。根据分隔符的位置,裁剪字节切片,只保留JSON数据部分。
反序列化JSON: 使用json.Unmarshal()函数将裁剪后的JSON数据反序列化为Go结构体。
示例代码
package main
import (
"bytes"
"encoding/json"
"fmt"
"os"
)
// MyStruct 定义JSON对应的结构体
type MyStruct struct {
Command string `json:"command"`
ID string `json:"id"`
Msg string `json:"msg,omitempty"` //omitempty表示如果Msg为空,则在JSON中不显示该字段
}
func main() {
// 创建一个缓冲区来保存流数据
data := make([]byte, 5000)
var err error
// 从stdin循环读取数据
for {
_, err = os.Stdin.Read(data)
if err != nil {
fmt.Println("Error reading from stdin:", err)
return // 或者使用 panic(err)
}
// 找到第一个换行符的索引
index := bytes.Index(data, []byte("\n"))
if index == -1 {
fmt.Println("No newline found, skipping")
continue // 或者返回错误
}
data = data[:index]
// 创建 MyStruct 类型的变量
var myStruct MyStruct
err = json.Unmarshal(data, &myStruct)
if err != nil {
fmt.Println("Error unmarshalling JSON:", err)
continue // 或者返回错误
}
// 使用 myStruct 做一些事情
fmt.Printf("Received: %+v\n", myStruct)
// 重置 data,准备读取下一个 JSON
data = make([]byte, 5000)
}
}代码解释
- MyStruct:定义了一个Go结构体,用于存储反序列化后的JSON数据。
- os.Stdin.Read(data):从标准输入读取数据到data字节切片。
- bytes.Index(data, []byte("\n")):查找data中第一个换行符的位置,用于确定JSON数据的边界。
- data = data[:index]:裁剪data,只保留JSON数据部分。
- json.Unmarshal(data, &myStruct):将JSON数据反序列化到myStruct结构体中。
- fmt.Printf("Received: %+v\n", myStruct):打印反序列化后的结构体内容。
注意事项
- 错误处理: 示例代码中使用了简单的错误处理方式。在实际应用中,应该根据具体情况进行更完善的错误处理,例如记录日志、返回错误码等。
- 缓冲区大小: 缓冲区大小5000是一个示例值,应该根据实际JSON数据的长度进行调整。如果JSON数据长度超过缓冲区大小,会导致数据丢失。
- 分隔符: 示例代码中使用换行符\n作为JSON数据和非JSON内容之间的分隔符。如果实际情况使用其他分隔符,需要相应地修改bytes.Index()函数的参数。
- 性能: 这种方法每次都需要读取整个缓冲区并进行裁剪,在处理大量数据时可能会影响性能。如果对性能要求较高,可以考虑使用流式处理或其他更高效的方案。
- 数据清洗: 确保在反序列化之前,对数据进行必要的清洗和验证,以防止恶意JSON数据导致的安全问题。
总结
该方法提供了一种在Go语言中处理包含非JSON内容的JSON流的有效解决方案。通过手动读取和裁剪数据,可以绕过标准json.Decoder的限制,成功解析这类数据流。但是,在实际应用中需要注意错误处理、缓冲区大小、分隔符以及性能等问题,并根据具体情况进行相应的调整和优化。
本篇关于《Go处理非JSON数据的JSON流方法》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于Golang的相关知识,请关注golang学习网公众号!
-
505 收藏
-
503 收藏
-
502 收藏
-
502 收藏
-
502 收藏
-
229 收藏
-
190 收藏
-
324 收藏
-
180 收藏
-
228 收藏
-
483 收藏
-
353 收藏
-
226 收藏
-
186 收藏
-
288 收藏
-
104 收藏
-
268 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习