You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JsonTextReader读取大JSON中单个对象的多字段值?

处理大JSON文件的解决方案

问题核心

  • 读取1.2GB级大型JSON,无需预定义实体类,支持facilities.totalSize.value这类路径式访问嵌套值
  • 现有代码触发“Object reference not set to an instance of an object”空引用错误
  • 需要适配两类JSON结构:无包装的对象数组、带listings/products等键名的嵌套数组
  • 需求为逐个处理列表对象,读取指定多类型字段(如整数countryid、字符串country、日期publishdate)

原代码错误原因

  1. 当reader.TokenType = JsonToken.StartObject时,直接将reader.Value转为JToken是错误操作——此时reader.Value为空,正确做法是用JToken.Load(reader)加载整个对象,但加载后reader会自动移动到对象的EndToken位置,不能重复读取
  2. 未对SelectToken的返回值做空值判断,一旦指定路径不存在就会触发空引用错误
  3. 未区分JSON根结构类型,遍历逻辑无法适配数组和带键对象两种场景

解决方案代码(VB.NET)

基于Newtonsoft.Json(Json.NET)实现流式处理,自动适配不同JSON结构:

Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq

' 单个对象处理逻辑,可按需扩展字段读取规则
Sub ProcessSingleObject(obj As JObject)
    ' 读取嵌套路径值,先判空避免空引用
    Dim totalSize = obj.SelectToken("facilities.totalSize.value")
    If totalSize IsNot Nothing Then
        Log($"jt totalSize: {totalSize.ToString()}")
    End If

    ' 多类型字段读取示例
    Dim countryId = obj.SelectToken("countryid")?.Value(Of Integer)()
    Dim country = obj.SelectToken("country")?.Value(Of String)()
    Dim publishDate = obj.SelectToken("publishdate")?.Value(Of DateTime)()

    ' 此处添加自定义业务处理
    If countryId IsNot Nothing Then
        Log($"Country ID: {countryId}")
    End If
End Sub

' 大JSON读取主逻辑
Sub ReadLargeJson(url As String)
    Dim req As HttpWebRequest = CType(WebRequest.Create(url), HttpWebRequest)
    Using resp = req.GetResponse()
        Using stream = resp.GetResponseStream()
            Using reader = New JsonTextReader(New StreamReader(stream))
                ' 先读取首个Token判断根结构
                reader.Read()

                Select Case reader.TokenType
                    Case JsonToken.StartArray
                        ' 处理无包装的对象数组
                        While reader.Read()
                            If reader.TokenType = JsonToken.StartObject Then
                                Dim obj = JObject.Load(reader)
                                ProcessSingleObject(obj)
                            End If
                        End While

                    Case JsonToken.StartObject
                        ' 处理带键的嵌套数组结构
                        Dim rootObj = JObject.Load(reader)
                        ' 匹配常见数组键名,可根据实际场景扩展
                        Dim arrayToken As JToken = Nothing
                        For Each key In {"listings", "products"}
                            arrayToken = rootObj(key)
                            If arrayToken?.Type = JTokenType.Array Then
                                Exit For
                            End If
                        Next

                        If arrayToken IsNot Nothing Then
                            ' 逐个处理数组内的对象
                            For Each item In arrayToken.Children(Of JObject)()
                                ProcessSingleObject(item)
                            Next
                        End If
                End Select
            End Using
        End Using
    End Using
End Sub

关键优化点

  • 流式处理:避免一次性加载1.2GB JSON到内存,仅加载单个对象完成处理后释放资源
  • 空值安全:所有SelectToken调用后通过?.做空值判断,彻底避免空引用错误
  • 结构适配:自动识别根结构是数组还是带键对象,支持多种数组键名
  • 类型安全:通过Value(Of T)指定字段类型,确保类型转换准确

注意事项

  1. 需提前安装Newtonsoft.Json NuGet包,这是高效处理大JSON的核心依赖
  2. 若数组键名不确定,可遍历根对象所有属性,判断属性类型是否为数组
  3. 处理日期字段时,若JSON日期格式不符合.NET默认规则,可通过JsonSerializerSettings指定自定义解析格式

内容的提问来源于stack exchange,提问作者Adam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 06:01:16