Leggi e analizza un file Json in C #


240

Ho trascorso la maggior parte dei due giorni a "affannarmi" con esempi di codice e così via, cercando di leggere un file JSON molto grande in un array in c #, in modo da poterlo dividere successivamente in un array 2d per l'elaborazione.

Il problema che stavo avendo era che non riuscivo a trovare esempi di persone che facessero quello che stavo cercando di fare. Ciò significava che stavo solo modificando un po 'il codice sperando per il meglio.

Sono riuscito a far funzionare qualcosa che:

  • Leggi il file Perdere le intestazioni e leggere solo i valori nell'array.
  • Inserire una certa quantità di valori su ciascuna riga di un array. (Quindi ho potuto dividerlo in seguito in un array 2d)

Ciò è stato fatto con il codice seguente, ma si arresta in modo anomalo al programma dopo aver inserito alcune righe nell'array. Ciò potrebbe avere a che fare con la dimensione del file.

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

Un frammento del JSON con cui sto lavorando è:

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

Ho bisogno dei valori di questo JSON. Ad esempio, ho bisogno di "3.54", ma non vorrei che stampasse il "vcc".

Spero che qualcuno possa mostrarmi come leggere un file JSON ed estrarre solo i dati di cui ho bisogno e metterli in un array o qualcosa che posso usare per inserire successivamente in un array.


1
Quale eccezione genera il tuo programma quando si blocca?
martedì

1
Questo risponde alla tua domanda? Come posso analizzare JSON con C #?
Heretic Monkey

Risposte:


484

Che ne dici di rendere tutto più semplice con 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;
}

Puoi persino ottenere i valori dynamicalleati senza dichiarare la Itemclasse.

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

1
@ChrisDevine Spero che tu non abbia inserito il percorso come json. Deve essere il contenuto del tuo file.
LB

4
StreamReader ("file.json") ha bisogno di uno Stream non di una stringa
vg

13
In C # DotNet Core, utilizzare: using (StreamReader r = File.OpenText ("file.json"))
Fred

20
Per coloro che non amano leggere le altre risposte per capirlo: questa soluzione richiede il pacchetto Json.net (Newtonsoft.Json)
Tydaeus,

1
Dato che hai StreamReadercomunque, sarebbe meglio deserializzare direttamente dallo stream usando JsonTextReadercome mostrato in Json.NET può serializzare / deserializzare su / da uno stream? . Non r.ReadToEnd()è necessario.
dbc

43

Farlo da soli è un'idea terribile. Usa Json.NET . Ha già risolto il problema meglio della maggior parte dei programmatori se avessero avuto mesi e mesi di lavoro su di esso. Per quanto riguarda le tue esigenze specifiche, analizzando array e simili, controlla la documentazione , in particolare su JsonTextReader. Fondamentalmente, Json.NET gestisce le matrici JSON in modo nativo e le analizzerà in stringhe, ints o qualunque altra cosa il tipo capiti di essere senza richiederti. Ecco un link diretto agli usi del codice di base sia per il lettore che per lo scrittore, quindi puoi averlo aperto in una finestra di riserva mentre stai imparando a lavorare con questo.

Questo è per il meglio: questa volta sii pigro e usa una libreria per risolvere questo problema comune per sempre.


1
Sto usando Json.net ma non capisco come funzioni correttamente. quando leggo le informazioni usando JsonTextReader in una casella di testo ottengo tutti i bit di dati ma anche le intestazioni ecc. Voglio solo i vaule nelle intestazioni. Ho provato a leggere la documentazione di Json.NET ma non l'ho trovata, mi spiega tutto ciò che mi serve per usarlo come vorrei
Chris Devine,

@ChrisDevine "Json headers"? Ti riferisci alle chiavi? Forse questo sarebbe più facile se hai pubblicato un breve frammento di JSON (~ 10-15 righe) e punti esattamente ciò che stai cercando di estrarre.
martedì

@ChrisDevine Ho appena aggiunto il tuo commento qui alla tua domanda, quindi se potessi gentilmente eliminare il commento sopra questo sarebbe fantastico.
martedì

@ChrisDevine Inoltre, se potessi rispondere al commento che ho sulla tua domanda, sarebbe fantastico.
martedì

1
@ChrisDevine Sì, sto dicendo che l'ho messo nella tua domanda, quindi non è più necessario qui.
martedì

12

Basato sulla soluzione di @ LB, il codice VB (digitato come Objectanziché Anonymous) è

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

Devo dire che questo è rapido e utile per costruire contenuti di chiamate HTTP dove il tipo non è richiesto. E usando Objectpiuttosto che Anonymoussignifica che puoi mantenerti Option Strict Onnel tuo ambiente Visual Studio - odio spegnerlo.


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

Per trovare la strada giusta che sto usando

   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 utilizza Path.PathSeparator e verifica se il primo percorso ha già un separatore alla fine, quindi non duplicherà i separatori. Inoltre, controlla se gli elementi del percorso da combinare hanno caratteri non validi.

Vedi https://stackoverflow.com/a/32071002/4420355


2
Modo migliore per trovare il percorso assoluto indipendentemente dall'applicazione: stackoverflow.com/questions/15653921/get-current-folder-path/...
user3326078

3

Per qualsiasi analisi JSON, utilizzare il sito Web http://json2csharp.com/ (modo più semplice) per convertire il proprio JSON in classe C # per deserializzare il proprio JSON in oggetto 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; }        
 }

Quindi utilizzare JavaScriptSerializer (da System.Web.Script.Serialization), nel caso in cui non si desideri alcuna DLL di terze parti come newtonsoft.

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

Quindi puoi ottenere il tuo oggetto con Items.name o Items.Url ecc.


3

Questo può essere fatto anche nel modo seguente:

JObject data = JObject.Parse(File.ReadAllText(MyFilePath));
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.