读取包含多条JSON消息的文本文件

本文关键字:文本 文件 消息 JSON 包含多 读取 | 更新日期: 2023-09-27 17:59:45

我有一个文本文件,其中包含多个JSON消息。除了换行符外,没有分隔符。我有一个方法,它将接收JSON字符串并将其反序列化为某种对象类型。

如何读取文本文件并遍历每个Json字符串,以便对其进行反序列化?

以下是反序列化的方法:

public static T JsonDeserialize<T>(string jsonString)
{
    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
    MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
    T obj = (T)ser.ReadObject(ms);
    return obj;
}

读取包含多条JSON消息的文本文件

您可以使用jsonReader。SupportMultipleContent属性
消息换行符、制表符或空格之间的分隔并不重要。

SupportMultipleContent设置一个值true/false(默认值为false),指示是否可以从连续流中读取多条JSON内容而不会出错。

示例:

public static void Main()
{   
    string json = @"
    {
        'Name': 'foo',
        'Id': 123
    }{
        'Name': 'bar',
        'Id': 456
    }
    
    //more new line
    {
        'Name': 'jar',
        'Id': 789
    }
    ";
     var persons = DeserializeObjects<Person>(json).ToList();
     Console.WriteLine(persons.Count());
     foreach ( var person in persons)
    {
      Console.WriteLine("id: {0}, Name: {1}",person.Id, person.Name);
    }

}

    static IEnumerable<T> DeserializeObjects<T>(string input)
    {
        JsonSerializer serializer = new JsonSerializer();
        using (var strreader = new StringReader(input)) 
        using (var jsonreader = new JsonTextReader(strreader))
        {
                //you should use this line
                jsonreader.SupportMultipleContent = true;
                while (jsonreader.Read()) 
                {                       
                    yield return  serializer.Deserialize<T>(jsonreader);
                }
            
        }
    }
     
    class Person
    {
      public int Id {get;set;}
      public string  Name {get;set;}
    }

在线试用

输出:

3

id:123,名称:foo

id:456,名称:bar

id:789,名称:jar

我唯一能想到的就是循环遍历每个字符并计算括号。当括号计数为零时,它将把组合字符串添加到列表中。最后,您将看到一个单独的JSON字符串列表。

public List<string> GetJsonItems()
{
    int BracketCount = 0;
    string ExampleJSON = new StreamReader(@"c:'Json.txt").ReadToEnd();
    List<string> JsonItems = new List<string>();
    StringBuilder Json = new StringBuilder();
    foreach (char c in ExampleJSON)
    {
        if (c == '{')
            ++BracketCount;
        else if (c == '}')
            --BracketCount;
        Json.Append(c);
        if (BracketCount == 0 && c != ' ')
        {
            JsonItems.Add(Json.ToString());
            Json = new StringBuilder();
        }
    }
    return JsonItems;    
}

编辑:将代码更改为使用StringBuilder,现在速度更快了。几乎立即解析出2MB的JSON文件。

您还可以拆分文本文件并遍历每个JSON部分。

类似这样的东西:

void ReadJsonWithLinebreaks(string jsonFilePath)
{
        string jsonFileContent = File.ReadAllText(jsonFilePath);
        string[] jsonContentSplitted = jsonFileContent.Split(Environment.NewLine.ToCharArray());
        // ... iterate through array that contains your JSON content
}

编辑:如果JSON文件带有换行符,请使用File.ReadAllLines()而不是File.ReadAllText

如果Json字符串由新行分隔,则可以遍历所有行,并使用以下代码进行解析:

List<YourClass> objects = new List<YourClass>();
String[] lines = File.ReadAllLines("path'to'file.txt");
foreach (string line in lines)
{
    try
    {
        var obj = JsonDeserialize<YourClass>(line);
        objects.Add(obj);
    }
    catch (Exception) { }
}

如果这对你没有帮助,请发布一个示例文件。

我建议使用StreamReader类。这有一个方法ReadLine(),它将一次返回一条json消息。您可以在读取文件时调用JsonDeserialize函数,也可以将所有消息放入列表中,稍后进行反序列化。

List<MyClass> deserializedObjects = new List<MyClass>();
using(var reader = new StreamReader(pathToFile)){
    while(!reader.EndOfStream){
        deserializedObjects.Add(JsonDeserialize<MyClass>(reader.ReadLine()));
    }
}