0

0

处理Go中JSON流中的非JSON内容

DDD

DDD

发布时间:2025-10-18 10:06:24

|

323人浏览过

|

来源于php中文网

原创

处理go中json流中的非json内容

本文介绍了一种在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结构体。

实现步骤

  1. 读取字节切片: 使用os.Stdin.Read()从标准输入读取数据到一个字节切片中。需要预先分配足够大的字节切片来容纳可能的数据。

  2. 裁剪非JSON内容: 使用bytes.Index()函数查找JSON数据和非JSON内容之间的分隔符。根据分隔符的位置,裁剪字节切片,只保留JSON数据部分。

  3. 反序列化JSON: 使用json.Unmarshal()函数将裁剪后的JSON数据反序列化为Go结构体。

    移动端无限滚动加载瀑布流
    移动端无限滚动加载瀑布流

    里面有2个文件夹。其中这个文件名是:finishing,是我项目还没有请求后台的数据的模拟写法。请求后台数据之后,瀑布流的js有一点点变化,放在文件名是:finished。变化在于需要穿参数到后台,和填充的内容都用后台的数据填充。看自己项目需求来。由于chrome模拟器是不允许读取本地文件json的,所以如果你要进行测试,在hbuilder打开项目就可以看到效果啦,或者是火狐浏览器。

    下载

示例代码

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的限制,成功解析这类数据流。但是,在实际应用中需要注意错误处理、缓冲区大小、分隔符以及性能等问题,并根据具体情况进行相应的调整和优化。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

417

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

533

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

310

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

75

2025.09.10

printf用法大全
printf用法大全

php中文网为大家提供printf用法大全,以及其他printf函数的相关文章、相关下载资源以及各种相关课程,供大家免费下载体验。

73

2023.06.20

fprintf和printf的区别
fprintf和printf的区别

fprintf和printf的区别在于输出的目标不同,printf输出到标准输出流,而fprintf输出到指定的文件流。根据需要选择合适的函数来进行输出操作。更多关于fprintf和printf的相关文章详情请看本专题下面的文章。php中文网欢迎大家前来学习。

282

2023.11.28

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

258

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.04

html编辑相关教程合集
html编辑相关教程合集

本专题整合了html编辑相关教程合集,阅读专题下面的文章了解更多详细内容。

38

2026.01.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 8.4万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 3.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号