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


239

我花了两天的大部分时间来“打理”代码示例等,试图将一个非常大的JSON文件读入c#中的数组,以便稍后将其拆分为2d数组进行处理。

我遇到的问题是,我找不到任何有人在做我想做的事的例子。这意味着我只是在编辑代码,以期获得最佳效果。

我设法使某些东西能够工作:

  • 读取文件Miss out标头,仅将值读入数组。
  • 在数组的每一行上放置一定数量的值。(所以我以后可以将它分割成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文件,并且仅提取所需的数据并将其放入数组或以后可用于数组的内容。


1
程序崩溃时会抛出什么异常?
tmesser 2012年

1
这回答了你的问题了吗?如何使用C#解析JSON?
异端猴子

Answers:


483

如何用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
@ChrisDevine希望您不要把路径设置为json。它必须是文件的内容。
LB 2012年

4
StreamReader(“ file.json”)需要流而不是字符串
vg

13
在C#DotNet Core中,使用:using(StreamReader r = File.OpenText(“ file.json”))
Fred

20
对于不喜欢阅读其他答案的人们来理解这个答案:此解决方案需要Json.net软件包(Newtonsoft.Json)
Tydaeus

1
既然您仍然有StreamReader,最好使用Json.NET可以序列化/反序列化到/从流中直接JsonTextReader显示,直接从流中反序列化。。该r.ReadToEnd()是没有必要的。
dbc

43

自己做这是一个可怕的主意。使用Json.NET。它已经比大多数程序员花了几个月的时间来解决这个问题更好地解决了这个问题。根据您的特定需求,解析为数组等,请查阅文档,尤其是参考资料JsonTextReader。基本上,Json.NET会本地处理JSON数组,并将其解析为字符串,整数或任何类型的碰巧,而无需您的提示。 是阅读器和编写器的基本代码用法的直接链接,因此在学习使用此方法时,可以在备用窗口中将其打开。

这是最好的:这次懒惰,并使用一个库,以便您永久解决此常见问题


1
我正在使用Json.net,但我不知道它如何正常工作。当我使用JsonTextReader将信息读取到文本框中时,我得到了每一位数据,而且还有标题等。我只想要标题中的值。我试图阅读Json.NET文档,但没有找到足以让我以自己想要的方式使用它的东西
Chris Devine

@ChrisDevine“ Json标头”?您指的是钥匙吗?如果发布一小段(约10-15行)JSON并准确指出要提取的内容,这可能会更容易。
tmesser 2012年

@ChrisDevine我只是在这里将您的评论添加到您的问题中,因此,如果您可以删除此评论上方的评论,那将很好。
tmesser 2012年

@ChrisDevine另外,如果您可以回答我对您的问题的评论,那就太好了。
tmesser 2012年

1
@ChrisDevine是的,我是说我把它放在您的问题中,因此在这里不再需要。
tmesser 2012年

12

根据@LB的解决方案,(键入为Object而不是Anonymous)VB代码为

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

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


7
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
        }

3

为了找到正确的路径,我正在使用

   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


2
不管应用程序如何,找到绝对路径的更好方法:stackoverflow.com/questions/15653921/get-current-folder-path/…–
user3326078

3

对于任何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),以防您不希望使用任何第三方DLL(例如newtonsoft)。

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等获取对象。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.