如何将大型JSON数据反序列化为DataGridView

如何将大型JSON数据反序列化为DataGridView,json,vb.net,datagridview,json.net,json-deserialization,Json,Vb.net,Datagridview,Json.net,Json Deserialization,我希望将一个大JSON文件(~600MB)反序列化到DataGridView中,而不会遇到“maxJsonLength”错误 我的代码对于小JSON文件来说运行良好。但是对于更大的JSON文件,我会得到“maxJsonLength”错误。既然我不是最有经验的程序员,有没有解决这个问题的方法或简单的方法 Private Sub BtnOpenFile_Click(sender As Object, e As EventArgs) Handles BtnOpenFileOld.Click

我希望将一个大JSON文件(~600MB)反序列化到DataGridView中,而不会遇到“maxJsonLength”错误

我的代码对于小JSON文件来说运行良好。但是对于更大的JSON文件,我会得到“maxJsonLength”错误。既然我不是最有经验的程序员,有没有解决这个问题的方法或简单的方法

Private Sub BtnOpenFile_Click(sender As Object, e As EventArgs) Handles BtnOpenFileOld.Click
        OpenFileDialog1.InitialDirectory = "C:\"

        If OpenFileDialog1.ShowDialog = DialogResult.Cancel Then
        End If

        Dim JSonFilePath As String = File.ReadAllText(OpenFileDialog1.FileName)
        LblFilePath.Text = OpenFileDialog1.FileName

        DataGridView1.Rows.Clear()
        DataGridView1.Refresh()

        Dim dict As Object = New JavaScriptSerializer().Deserialize(Of List(Of Object))(JSonFilePath)

        For Each item As Object In dict
            DataGridView1.Rows.Add(item("EMail").ToString, item("Timestamp").ToString, item("Number").ToString)
        Next

    End Sub
我的JSON文件看起来像

[
  {
    "EMail": "one@mail.com",
    "Timestamp": "2019-05-25T21:24:06.799381+02:00",
    "Number": 206074,
    "randomtrash1": "notneeded",
    "randomtrash2": "notneeded",
    "randomtrash3": "notneeded",
    "randomtrash4": "notneeded",
    "randomtrash5": "notneeded",
    "randomtrash6": "notneeded",
    "randomtrash7": "notneeded",
    "randomtrash8": "notneeded",
    "randomtrash9": "notneeded"
  },
  {
    "EMail": "two@mail.com",
    "Timestamp": "2019-05-25T21:24:06.8273826+02:00",
    "Number": 7397,
    "randomtrash1": "notneeded",
    "randomtrash2": "notneeded",
    "randomtrash3": "notneeded",
    "randomtrash4": "notneeded",
    "randomtrash5": "notneeded",
    "randomtrash6": "notneeded",
    "randomtrash7": "notneeded",
    "randomtrash8": "notneeded",
    "randomtrash9": "notneeded",
    "randomtrash10": "notneeded",
    "randomtrash11": "notneeded",
    "randomtrash12": "notneeded",
    "randomtrash13": "notneeded",
    "randomtrash14": "notneeded",
    "randomtrash15": "notneeded",
    "randomtrash16": "notneeded",
    "randomtrash17": "notneeded",
    "randomtrash18": "notneeded",
    "randomtrash19": "notneeded",
    "randomtrash20": "notneeded",
    "randomtrash21": "notneeded"
  }
]


避免
maxJsonLength
错误的最小修复方法是设置为,如下所示:

但是,您当前正在将一个600MB的文件加载到一个接近.Net的600-1200MB字符串中。如果文件变大,则会出现内存不足异常。更好的方法是使用流解决方案直接从文件反序列化,但是
JavaScriptSerializer
不支持流。因此,我建议切换到,确实如此

首先,安装Json.NET,如图所示。接下来,由于您似乎不想为JSON定义显式数据模型,请创建以下静态方法:

Public Module JsonExtensions
    Public Function LoadAnonymousType(Of T)(ByVal path as String, ByVal anonymousTypeObject as T, Optional ByVal settings as JsonSerializerSettings = Nothing) as T
        Using streamReader As TextReader = File.OpenText(path)
            Dim serializer = JsonSerializer.CreateDefault(settings)
            return CType(serializer.Deserialize(streamreader, GetType(T)), T)
        End Using
    End Function
End Module
这样做的目的是将位置由
path
参数指定的文件的内容反序列化为
anonymousTypeObject
参数指定类型的数据模型

现在,您可以直接将JSON从文件反序列化为一个数组,如下所示:

Dim array = JsonExtensions.LoadAnonymousType( _
    FileName, _
    { New With {.Email = CType(Nothing, String), .Timestamp = CType(Nothing, String), .Number = CType(Nothing, Long) }} _
)
For Each item In array
    ' DataGridView1.Rows.Add(item("EMail").ToString, item("Timestamp").ToString, item("Number").ToString)
    Console.WriteLine("Email = {0}, Timestamp = {1}, Number = {2}", item.Email, item.Timestamp, item.Number)
Next
Public Class RootObject
    Public Property Email As String
    Public Property Timestamp As String
    Public Property Number As Long
End Class
或者,您可以创建一个显式数据模型,如下所示:

Dim array = JsonExtensions.LoadAnonymousType( _
    FileName, _
    { New With {.Email = CType(Nothing, String), .Timestamp = CType(Nothing, String), .Number = CType(Nothing, Long) }} _
)
For Each item In array
    ' DataGridView1.Rows.Add(item("EMail").ToString, item("Timestamp").ToString, item("Number").ToString)
    Console.WriteLine("Email = {0}, Timestamp = {1}, Number = {2}", item.Email, item.Timestamp, item.Number)
Next
Public Class RootObject
    Public Property Email As String
    Public Property Timestamp As String
    Public Property Number As Long
End Class
并反序列化,如所示:

演示小提琴


这是一个屏幕截图

为什么要使用
JavaScriptSerializer
?为什么不使用或甚至不使用
DataContractJsonSerializer
?如果您确定要使用
JavaScriptSerializer
,那么这是,不过,有更好的解决方案可以让您直接从文件中流式传输,而无需预加载到600-1200 MB的字符串中。因为我不知道如何使用json.net,所以我找到的关于json.net的所有示例都是c#。因此,“JavaScriptSerializer”对我来说似乎是最简单的方法,在我达到maxJsonLength
之前,它工作得相当好。我找到的所有关于json.net的示例都是在c#
FYI中,您可以随时将这些示例转换为VB.net。
Imports Newtonsoft.Json

Public Class Form1

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    Dim str As String = _
            "[" + _
            "  {" + _
            "    ""EMail"": ""one@mail.com""," + _
            "    ""Timestamp"": ""2019-05-25T21:24:06.799381+02:00""," + _
            "    ""Number"": 206074," + _
            "  }," + _
            "  {" + _
            "    ""EMail"": ""two@mail.com""," + _
            "    ""Timestamp"": ""2019-05-25T21:24:06.8273826+02:00""," + _
            "    ""Number"": 7397," + _
            "  }," + _
            "]"

    Try
        Dim list As List(Of jsnn) = JsonConvert.DeserializeObject(Of List(Of jsnn))(str)

        For Each item As jsnn In list
            Console.WriteLine(item.EMail & ": " & item.Timestamp & ": " & item.Number)
        Next

    Catch ex As Exception
        MsgBox(ex.Message)
    End Try

End Sub

End Class

Public Class jsnn
    Public Property EMail As String
    Public Property Timestamp As DateTime
    Public Property Number As Integer
End Class