在C#中读取和解析Json文件

时间:2012-11-08 20:50:37

标签: c# json parsing large-files

我花了两天的时间来讨论代码示例等等,尝试将一个非常大的JSON文件读入c#中的数组,以便稍后将其拆分为二维数组进行处理。

我遇到的问题是我找不到任何人做我想做的事情的例子。这意味着我只是编辑代码,希望最好。

我已经成功完成了一些工作:

  • 读取文件Miss out headers并仅将值读入数组。
  • 在数组的每一行上放置一定数量的值。 (所以我 以后可以把它分成2d数组)

这是通过下面的代码完成的,但是在数组中输入几行后它会崩溃程序。这可能与文件大小有关。

// If the file extension was a jave file the following 
// load method will be use else it will move on to the 
// next else if statement
if (fileExtension == ".json") 
{
    int count = 0;
    int count2 = 0;
    int inOrOut = 0;
    int nRecords=1; 
    JsonTextReader reader = new JsonTextReader(new StreamReader(txtLoaction.Text));
    string[] rawData = new string[5];
    while (reader.Read())
    {
        if (reader.Value != null)
            if (inOrOut == 1)
            {
                if (count == 6)
                {
                    nRecords++;
                    Array.Resize(ref rawData, nRecords);
                    //textBox1.Text += "\r\n";
                    count = 0;
                }
                rawData[count2] += reader.Value + ","; //+"\r\n"
                inOrOut = 0;
                count++;
                if (count2 == 500)
                {
                    MessageBox.Show(rawData[499]);
                }
            }
            else
            {
                inOrOut = 1;
            }
    } 
}

我正在使用的JSON片段是:

[ 
    { "millis": "1000", 
      "stamp": "1273010254", 
      "datetime": "2010/5/4 21:57:34", 
      "light": "333", 
      "temp": "78.32", 
      "vcc": "3.54" }, 
] 

我需要这个JSON中的值。例如,我需要“3.54”,但我不希望它打印“vcc”。

我希望有人可以告诉我如何读取JSON文件并仅提取我需要的数据并将其放入数组或我可以用来稍后放入数组的内容。

10 个答案:

答案 0 :(得分:387)

如何使用Json.NET让所有事情变得更轻松?

public void LoadJson()
{
    using (StreamReader r = new StreamReader("file.json"))
    {
        string json = r.ReadToEnd();
        List<Item> items = JsonConvert.DeserializeObject<List<Item>>(json);
    }
}

public class Item
{
    public int millis;
    public string stamp;
    public DateTime datetime;
    public string light;
    public float temp;
    public float vcc;
}

您甚至可以在不声明dynamic课程的情况下获得值Item盟友。

dynamic array = JsonConvert.DeserializeObject(json);
foreach(var item in array)
{
    Console.WriteLine("{0} {1}", item.temp, item.vcc);
}

答案 1 :(得分:9)

这也可以通过以下方式完成:

JObject data = JObject.Parse(File.ReadAllText(MyFilePath));

答案 2 :(得分:8)

基于@ L.B。的解决方案,(键入为Object而不是Anonymous的VB代码是

Dim oJson as Object = JsonConvert.DeserializeObject(File.ReadAllText(MyFilePath))

我应该提到,这对于构造不需要类型的HTTP调用内容是快速且有用的。而且使用Object而不是Anonymous意味着您可以在Visual Studio环境中维护Option Strict On-我讨厌将其关闭。

答案 3 :(得分:3)

string jsonFilePath = @"C:\MyFolder\myFile.json";

        string json = File.ReadAllText(jsonFilePath);
        Dictionary<string, object> json_Dictionary = (new JavaScriptSerializer()).Deserialize<Dictionary<string, object>>(json);

        foreach (var item in json_Dictionary)
        {
            // parse here
        }

答案 4 :(得分:1)

找到我正在使用的正确路径

   var pathToJson = Path.Combine("my","path","config","default.Business.Area.json");
   var r = new StreamReader(pathToJson);
   var myJson = r.ReadToEnd();

   // my/path/config/default.Business.Area.json 
   [...] do parsing here 
  

Path.Combine使用Path.PathSeparator,它检查第一个路径是否在末尾已经有一个分隔符,因此它不会复制分隔符。此外,它还会检查要组合的路径元素是否具有无效字符。

请参阅https://stackoverflow.com/a/32071002/4420355

答案 5 :(得分:1)

对于任何JSON解析,请使用网站http://json2csharp.com/(最简单的方法)将JSON转换为C#类,以将JSON反序列化为C#对象。

 public class JSONClass
 {
        public string name { get; set; }
        public string url { get; set; }
        public bool visibility { get; set; }
        public string idField { get; set; }
        public bool defaultEvents { get; set; }
        public string type { get; set; }        
 }

然后使用JavaScriptSerializer(来自System.Web.Script.Serialization),以防万一您不想像newtonsoft这样的第三方DLL。

using (StreamReader r = new StreamReader("jsonfile.json"))
{
   string json = r.ReadToEnd();
   JavaScriptSerializer jss = new JavaScriptSerializer();
   var Items = jss.Deserialize<JSONClass>(json);
}

然后可以使用Items.name或Items.Url等获取对象。

答案 6 :(得分:1)

.NET Core 的答案

您可以使用内置的 System.Text.Json 而不是 3rd-party Json.NET。为了促进重用,JSON 文件读取功能属于它自己的类,应该是通用的,而不是硬编码到某个类型 (Item)。这是一个完整的示例:

using System;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;

namespace Project
{
    class Program
    {
        static async Task Main()
        {
            Item item = await JsonFileReader.ReadAsync<Item>(@"C:\myFile.json");
        }
    }

    public static class JsonFileReader
    {
        public static async Task<T> ReadAsync<T>(string filePath)
        {
            using FileStream stream = File.OpenRead(filePath);
            return await JsonSerializer.DeserializeAsync<T>(stream);
        }
    }

    public class Item
    {
        public int millis;
        public string stamp;
        public DateTime datetime;
        public string light;
        public float temp;
        public float vcc;
    }
}

或者,如果您喜欢更简单/同步的东西:

class Program
{
    static void Main()
    {
        Item item = JsonFileReader.Read<Item>(@"C:\myFile.json");
    }
}

public static class JsonFileReader
{
    public static T Read<T>(string filePath)
    {
        string text = File.ReadAllText(filePath);
        return JsonSerializer.Deserialize<T>(text);
    }
}

答案 7 :(得分:1)

有一种更简单的方法可以从文件或 Web 获取 JSON: Json.Net.Curl

<块引用>

安装包 Json.Net.Curl

// get JObject from local file system 
var json = Json.Net.Curl.Get(@"data\JObjectUnitTest1.json");
var json = await Json.Net.Curl.GetAsync(@"data\JObjectUnitTest1.json")


// get JObject from Server  
var json = await Json.Net.Curl.GetAsync("http://myserver.com/data.json");

GitHub Project Nuget

答案 8 :(得分:0)

此代码可以为您提供帮助:

string _filePath = Path.GetDirectoryName(System.AppDomain.CurrentDomain.BaseDirectory);

JObject data = JObject.Parse(_filePath );

答案 9 :(得分:0)

有一种解析 json 的更快方法,然后是 Json.Net。如果您使用 .net core 3.0 或更高版本,则可以使用 System.Text.Json nuget 包进行序列化或反序列化。

您需要添加:

using System.Text.Json

然后你可以反序列化为:

var jsonStr = JsonSerializer.Serialize(model);

反序列化为:

var model = JsonSerializer.Deserialize(jsonStr);