首页 > 后端开发 > Golang > 正文

使用 Go 处理包含非 JSON 内容的 JSON 流

碧海醫心
发布: 2025-10-18 11:34:01
原创
330人浏览过

使用 go 处理包含非 json 内容的 json 流

本文介绍了如何使用 Go 语言处理从标准输入读取的 JSON 数据流,该数据流中 JSON 结构体之间穿插着非 JSON 字符串(例如 "end")。我们将探讨如何读取数据流,过滤掉非 JSON 内容,并将有效的 JSON 数据反序列化为 Go 结构体。

处理混合 JSON 和非 JSON 内容的数据流

在某些情况下,我们可能需要处理包含 JSON 数据和其他类型数据的混合数据流。例如,一个应用程序可能通过标准输入发送 JSON 结构体,并在每个结构体之后添加一个 "end" 字符串作为分隔符。Go 的 encoding/json 包默认情况下无法直接处理这种数据流,因为它期望输入是纯粹的 JSON 格式。

以下是一种处理这种情况的方法,它放弃了 json.Decoder,转而使用 io.Reader 和 json.Unmarshal:

示例代码

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)

    // 从 stdin 循环读取数据
    for {
        n, err := os.Stdin.Read(data)
        if err != nil {
            fmt.Println("Error reading from stdin:", err)
            return // 或者根据需要进行错误处理
        }

        // 查找换行符的索引,用于分隔 JSON 结构
        index := bytes.Index(data[:n], []byte("\n"))

        // 如果没有找到换行符,则继续读取更多数据
        if index == -1 {
            fmt.Println("No newline found, reading more data")
            continue
        }

        // 提取 JSON 数据部分
        jsonData := data[:index]

        // 创建 MyStruct 实例
        var myStruct MyStruct

        // 将 JSON 数据反序列化到 MyStruct
        err = json.Unmarshal(jsonData, &myStruct)
        if err != nil {
            fmt.Println("Error unmarshalling JSON:", err)
            continue // 或者根据需要进行错误处理
        }

        // 对 myStruct 进行操作
        fmt.Printf("Received: %+v\n", myStruct)

        // 移除已处理的数据和 "end\n" 字符串
        remainingData := data[index+len("\nend\n"):]
        copy(data, remainingData)

        // 重置 buffer 的剩余部分
        for i := len(remainingData); i < len(data); i++ {
            data[i] = 0
        }
    }
}
登录后复制

代码解释:

  1. 定义结构体: MyStruct 定义了要从 JSON 数据反序列化到的 Go 结构体。 json:"command" 等标记用于指定 JSON 字段与结构体字段之间的映射关系。
  2. 读取数据: 使用 os.Stdin.Read(data) 从标准输入读取数据到缓冲区 data 中。
  3. 查找分隔符: bytes.Index(data[:n], []byte("\n")) 查找换行符的索引,用于分隔 JSON 结构体和 end 字符串。 data[:n] 确保只在实际读取到的数据范围内查找。
  4. 提取 JSON 数据: jsonData := data[:index] 提取 JSON 数据部分。
  5. 反序列化 JSON: json.Unmarshal(jsonData, &myStruct) 将 JSON 数据反序列化到 MyStruct 结构体中。
  6. 错误处理: 代码包含错误处理逻辑,用于处理读取和反序列化过程中可能出现的错误。
  7. 移除已处理的数据: remainingData := data[index+len("\nend\n"):] 获取剩余未处理的数据,并将数据复制到 data 缓冲区的起始位置。 copy(data, remainingData) 确保数据不会丢失。
  8. 重置缓冲区: 将缓冲区中剩余部分重置为 0,避免旧数据干扰下一次读取。

编译并运行代码

将代码保存为 main.go,然后在终端中运行以下命令:

go run main.go
登录后复制

现在,你可以向标准输入发送包含 JSON 数据和 "end" 字符串的混合数据流。例如:

营销型印刷品包装企业网站织梦源码
营销型印刷品包装企业网站织梦源码

营销型印刷品包装企业网站织梦模板(带html5手机端)v1.0是一个自适应手机端和PC端的最新版织梦V5.7为内核的网站模板,软件兼容主流浏览器,模板包含安装说明,并包含测试数据,dedecms最新版内核开发,原创设计、手工书写DIV+CSS,完美兼,IE7+、Firefox、Chrome、360浏览器等;主流浏览器;页面简洁简单,容易管理,DEDE内核都可以使用;附带测试数据!

营销型印刷品包装企业网站织梦源码 84
查看详情 营销型印刷品包装企业网站织梦源码
echo '{"command": "ack", "id": "1231231"}' | cat - && echo 'end' | cat - && echo '{"command": "fail", "id": "1231231"}' | cat - && echo 'end' | cat -
登录后复制

或者,你可以将数据存储在文件中,然后使用以下命令将文件内容重定向到程序的标准输入:

cat input.txt | go run main.go
登录后复制

其中 input.txt 包含以下内容:

{"command": "ack", "id": "1231231"}
end
{"command": "fail", "id": "1231231"}
end
{
    "command": "log",
    "msg": "hello world!"
}
end
登录后复制

程序将解析 JSON 数据并将其打印到控制台。

注意事项

  • 缓冲区大小: data := make([]byte, 5000) 定义了缓冲区的大小。你需要根据实际情况调整缓冲区的大小,以确保能够容纳完整的 JSON 结构体和分隔符。
  • 错误处理: 示例代码包含基本的错误处理,但在实际应用中,你可能需要更完善的错误处理机制,例如记录错误日志或采取其他补救措施。
  • 性能: 对于非常大的数据流,这种方法可能不是最有效的。在这种情况下,可以考虑使用流式 JSON 解析器,例如 github.com/json-iterator/go,它可以更有效地处理大型 JSON 数据。
  • 分隔符的灵活性: 代码假设分隔符始终是 "end\n"。如果分隔符可能发生变化,你需要修改代码以适应不同的分隔符。
  • 多余的 end 字符: 如果JSON数据中存在 end 字符,可能会导致解析错误。

总结

本文介绍了一种使用 Go 语言处理包含非 JSON 内容的 JSON 数据流的方法。通过使用 io.Reader 和 json.Unmarshal,我们可以灵活地读取数据流,过滤掉非 JSON 内容,并将有效的 JSON 数据反序列化为 Go 结构体。在实际应用中,你需要根据具体情况调整代码,例如缓冲区大小、错误处理和性能优化。

以上就是使用 Go 处理包含非 JSON 内容的 JSON 流的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

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