使用c#解析JSON文件

本文关键字:文件 JSON 解析 使用 | 更新日期: 2023-09-27 18:12:04

我编写了一个c#应用程序,可以逐行读取JSON文件并从中写入csv文件。我已经为每种csv格式创建了模型文件,这些模型的对象在解析时被实例化,然后在最后被写入csv。

For example:如果输入文件名是abc。json,为abc创建并实例化对象,将其存储在List等数据结构中,最后将其写入csv。

JSON文件:

{
  "Computer ID": "1697343078",
  "Application Name": "Reporting Services Service",
  "Date": "8'/25'/2015",
  "Count": "1"
}

我要解析的代码如下:

using (System.IO.StreamReader sr = new System.IO.StreamReader(sFile, Encoding.UTF8))
while ((line = sr.ReadLine()) != null)
                        {
    if (line.Contains("Computer ID") && counter == 4)
            {
              string[] tokens = line.Split(':');
              if (tokens.Length >= 2)
              {
                  resourceID = reg.Replace(tokens[1], "");
              }
              counter = counter - 1;
              line = sr.ReadLine();
          }
}

由于输入文件中的数据格式或其他字段不一致,解析失败。代码抛出异常,对该特定文件的解析完全失败。我希望我的代码拒绝要解析的记录,并继续解析文件中的其他记录,并最终为其生成csv。

我希望它的行为如下:逐行读取文件如果在解析时发生任何错误,不要实例化该对象,并继续解析该文件的其他行将对象写入csv

任何帮助都会很感激。

使用c#解析JSON文件

可以使用Json。. NET解析JSON数据。为此,您需要:

  1. 定义与JSON对象相对应的类。
  2. 当出现DateTime属性时,将其声明为可空值。如果遇到像"没有找到日期,所以没有返回数据"这样的字符串,那么可以在属性中存储空值。
  3. 创建您自己的DateTimeConverter,在解析可为空的DateTime时,尝试您可能遇到的各种日期时间格式。如果遇到无效的格式,返回null而不是抛出异常。
  4. 应用到DateTime属性使用JsonConverterAttribute

因此,给定以下转换器:

public class DateTimeConverter : IsoDateTimeConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(DateTime?);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        var token = JToken.Load(reader);
        // For various JSON date formats, see
        // http://www.newtonsoft.com/json/help/html/DatesInJSON.htm
        // Try in JavaScript constructor format: new Date(1234656000000)
        if (token.Type == JTokenType.Constructor)
        {
            try
            {
                var result = token.ToObject<DateTime?>(JsonSerializer.CreateDefault(new JsonSerializerSettings { Converters = new JsonConverter[] { new JavaScriptDateTimeConverter() } }));
                if (result != null)
                    return result;
            }
            catch (JsonException)
            {
            }
        }
        // Try ISO format: "2009-02-15T00:00:00Z"
        if (token.Type == JTokenType.String)
        {
            try
            {
                var result = token.ToObject<DateTime?>(JsonSerializer.CreateDefault(new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.IsoDateFormat }));
                if (result != null)
                    return result;
            }
            catch (JsonException)
            {
            }
        }
        // Try Microsoft format: "'/Date(1234656000000)'/"
        if (token.Type == JTokenType.String)
        {
            try
            {
                var result = token.ToObject<DateTime?>(JsonSerializer.CreateDefault(new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat }));
                if (result != null)
                    return result;
            }
            catch (JsonException)
            {
            }
        }
        if (token.Type == JTokenType.String)
        {
            // Add other custom cases as required.
        }
        return null;
    }
}

你可以这样应用到你的类:

public class ComputerData
{
    [JsonProperty("Computer ID")]
    public string ComputerID { get; set; }
    [JsonProperty("Application Name")]
    public string ApplicationName { get; set; }
    [JsonConverter(typeof(DateTimeConverter))]
    public DateTime? Date { get; set; }
    public int Count { get; set; }
}

小提琴例子。

您不需要JSON解析器。您所需要的只是尝试catch块,以在解析数据格式不正确的行中忽略异常。通过检查条件,您应该能够处理这个问题。

这里可能是一个解决方案,我以前做过这样的事情,但我后来在最后自己写了一个JSON解析器....

实体类

 public class Info {
     public string ComputerID {get;set;}
     public string ApplicationName {get;set;}
     ...
 }

用于解析文本,并在解析

时忽略错误。
 Info record = null;
 var recordSet = new List<Info>();
 using (System.IO.StreamReader sr = new System.IO.StreamReader(sFile, Encoding.UTF8))
 {
    while ((line = sr.ReadLine()) != null)
    {
         if (record==null){
                record = new Info();
                recordSet.Add(record)
         }
         try {
         } catch ( Exception e) {
          //You either log the data or ignore the exception here
         }
         //Check your property here, replace with your actual implementation here
         if (record.ComputerID!=null && record.ApplicationName!=null) {
               record = null;
         }
    }
 }

随着事情变得越来越复杂,您可能仍然需要一个解析器来处理它,但这实际上取决于您的需要。