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

从包含分隔符的 JSON 流中提取有效 JSON 数据

DDD
发布: 2025-10-18 08:03:10
原创
1025人浏览过

从包含分隔符的 json 流中提取有效 json 数据

本文介绍了如何从包含非 JSON 分隔符(如 "end" 字符串)的 JSON 数据流中提取有效的 JSON 数据。我们将探讨一种使用 Go 语言的标准库 encoding/json 和 bytes 来实现此目的的方法,该方法通过读取字节切片,移除分隔符,然后将剩余部分反序列化为 JSON 对象。

在处理来自外部应用程序的 JSON 数据流时,有时会遇到数据流中夹杂着非 JSON 格式的分隔符的情况。例如,每个 JSON 结构体后面跟着一个 "end" 字符串。Go 语言的 encoding/json 包的解码器在这种情况下会报错,因为它无法将 "end" 字符串解析为 JSON。本教程将介绍如何解决这个问题,从这样的数据流中提取有效的 JSON 数据。

解决方案:手动处理数据流

由于标准 JSON 解码器无法直接处理包含非 JSON 分隔符的数据流,我们需要手动处理数据流。具体步骤如下:

  1. 读取字节切片: 从 stdin 读取数据到一个字节切片中。
  2. 移除分隔符: 在字节切片中查找分隔符,并将其移除。
  3. 反序列化 JSON: 将剩余的字节切片反序列化为 JSON 对象。

以下是一个示例代码:

Find JSON Path Online
Find JSON Path Online

Easily find JSON paths within JSON objects using our intuitive Json Path Finder

Find JSON Path Online 30
查看详情 Find JSON Path Online
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "os"
)

type MyStruct struct {
    Command string `json:"command"`
    ID      string `json:"id"`
    Msg     string `json:"msg,omitempty"` //omitempty 可以在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 // 或者 panic(err) 如果你希望程序在发生错误时崩溃
        }

        // 查找换行符的位置,假设 JSON 数据以换行符结尾
        index := bytes.IndexByte(data[:n], '\n') // 只在读取到的数据范围内查找
        if index == -1 {
            fmt.Println("No newline found in the input")
            continue // 继续下一次循环
        }

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

        // 反序列化 JSON 数据
        var myStruct MyStruct
        err = json.Unmarshal(jsonData, &myStruct)
        if err != nil {
            fmt.Println("Error unmarshaling JSON:", err)
            continue // 继续下一次循环
        }

        // 处理 myStruct
        fmt.Printf("Received: %+v\n", myStruct)

        // 跳过 "end" 行
        // 假设 "end" 行紧随 JSON 数据之后,并且以换行符结尾
        endLine := make([]byte, 4) // "end\n" 的长度
        _, err = os.Stdin.Read(endLine)
        if err != nil {
            fmt.Println("Error reading 'end' line:", err)
            return // 或者 panic(err)
        }
        if string(endLine) != "end\n" && string(endLine) != "end\r" {
            fmt.Println("Expected 'end' line, but got:", string(endLine))
            // 如果不是 "end\n",可能需要采取其他错误处理措施
            // 例如,将 endLine 的内容放回 stdin 中,以便下次读取
        }
    }
}
登录后复制

代码解释:

  • MyStruct 定义了 JSON 数据的结构体。json:"command" 等标签用于指定 JSON 字段与结构体字段之间的映射关系。
  • os.Stdin.Read(data) 从标准输入读取数据到 data 字节切片中。
  • bytes.Index(data, []byte("\n")) 查找换行符的位置,用于分割 JSON 数据和分隔符。
  • json.Unmarshal(data, &myStruct) 将 JSON 数据反序列化到 myStruct 结构体中。
  • 错误处理:代码包含了错误处理逻辑,可以更健壮地处理输入流中的问题。例如,检查是否成功读取到 "end" 行,以及是否确实读取到了 "end\n"。
  • 跳过"end"行:在处理完JSON数据后,代码会尝试读取并验证"end"行,确保输入流的格式符合预期。

注意事项:

  • 此代码假设 JSON 数据以换行符结尾,"end" 字符串也以换行符结尾。你需要根据实际情况调整代码。
  • data := make([]byte, 5000) 创建了一个固定大小的缓冲区。如果 JSON 数据超过 5000 字节,则会导致数据丢失。建议使用动态缓冲区,或者根据实际情况调整缓冲区大小。
  • 错误处理:代码包含了基本的错误处理,但你可能需要根据实际情况添加更完善的错误处理机制。

总结

本教程介绍了一种从包含非 JSON 分隔符的数据流中提取有效 JSON 数据的方法。通过手动处理数据流,我们可以绕过标准 JSON 解码器的限制,从而成功解析 JSON 数据。这种方法虽然需要更多的代码,但它提供了更大的灵活性,可以处理各种复杂的数据流格式。在实际应用中,请务必根据具体情况调整代码,并添加完善的错误处理机制。

以上就是从包含分隔符的 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号