Lire et analyser un fichier Json en C #

240

J'ai passé la plus grande partie de deux jours à "me moquer" des échantillons de code, etc., à essayer de lire un très gros fichier JSON dans un tableau en c # afin de pouvoir le diviser plus tard en un tableau 2D pour le traitement.

Le problème que je rencontrais était que je ne pouvais trouver aucun exemple de personnes faisant ce que j'essayais de faire. Cela signifiait que je modifiais juste un peu le code en espérant le meilleur.

J'ai réussi à faire fonctionner quelque chose qui:

  • Lisez le fichier Manquez les en-têtes et ne lisez que les valeurs dans le tableau.
  • Placez une certaine quantité de valeurs sur chaque ligne d'un tableau. (Donc, je pourrais plus tard le diviser en un tableau 2D)

Cela a été fait avec le code ci-dessous mais il plante le programme après avoir entré quelques lignes dans le tableau. Cela peut être lié à la taille du fichier.

// 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 extrait du JSON avec lequel je travaille est:

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

J'ai besoin des valeurs de ce JSON. Par exemple, j'ai besoin de "3.54", mais je ne voudrais pas qu'il imprime le "vcc".

J'espère que quelqu'un peut me montrer comment lire un fichier JSON et extraire uniquement les données dont j'ai besoin et les placer dans un tableau ou quelque chose que je peux utiliser pour les mettre plus tard dans un tableau.

Chris Devine
la source
1
Quelle exception votre programme lève-t-il lorsqu'il se bloque?
tmesser
1
Est-ce que cela répond à votre question? Comment analyser JSON avec C #?
Heretic Monkey

Réponses:

484

Que diriez-vous de rendre toutes les choses plus faciles avec 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;
}

Vous pouvez même obtenir les valeurs dynamicalliées sans déclarer de Itemclasse.

dynamic array = JsonConvert.DeserializeObject(json);
foreach(var item in array)
{
    Console.WriteLine("{0} {1}", item.temp, item.vcc);
}
KG
la source
1
@ChrisDevine J'espère que vous n'avez pas indiqué le chemin json. Il doit s'agir du contenu de votre fichier.
LB
4
StreamReader ("file.json") a besoin d'une chaîne Stream not
vg
13
Dans C # DotNet Core, utilisez: using (StreamReader r = File.OpenText ("file.json"))
Fred
20
Pour les gens qui n'aiment pas lire les autres réponses pour comprendre celle-ci: cette solution nécessite le package Json.net (Newtonsoft.Json)
Tydaeus
1
Étant donné que vous en avez un de StreamReadertoute façon, il serait préférable de désérialiser directement à partir du flux en utilisant JsonTextReadercomme indiqué dans Can Json.NET sérialiser / désérialiser vers / à partir d'un flux? . Ce r.ReadToEnd()n'est pas nécessaire.
dbc
43

Faire cela vous-même est une terrible idée. Utilisez Json.NET . Il a déjà résolu le problème mieux que la plupart des programmeurs ne pouvaient le faire si on leur donnait des mois pour travailler dessus. Quant à vos besoins spécifiques, l'analyse en tableaux et autres, consultez la documentation , en particulier sur JsonTextReader. Fondamentalement, Json.NET gère les tableaux JSON de manière native et les analysera en chaînes, en entiers ou quel que soit le type sans qu'il vous soit demandé. Voici un lien direct vers les utilisations de code de base pour le lecteur et l'écrivain, afin que vous puissiez l'ouvrir dans une fenêtre de rechange pendant que vous apprenez à travailler avec cela.

C'est pour le mieux: soyez paresseux cette fois et utilisez une bibliothèque pour résoudre ce problème commun pour toujours.

tmesser
la source
1
J'utilise Json.net mais je ne comprends pas comment cela fonctionne correctement. quand je lis les informations en utilisant JsonTextReader dans une zone de texte, j'obtiens chaque bit de données mais aussi des en-têtes, etc. Je veux juste les vaules dans les en-têtes. J'ai essayé de lire la documentation de Json.NET mais je n'ai pas trouvé qu'elle expliquait tout ce qui me suffisait pour l'utiliser comme je le voudrais
Chris Devine
@ChrisDevine "En-têtes Json"? Parlez-vous des clés? Ce serait peut-être plus facile si vous publiez un court extrait (~ 10-15 lignes) de JSON et montrez précisément ce que vous essayez d'extraire.
tmesser
@ChrisDevine Je viens d'ajouter votre commentaire ici à votre question, donc si vous pouviez bien vouloir supprimer le commentaire au-dessus de celui-ci, ce serait génial.
tmesser
@ChrisDevine De plus, si vous pouviez répondre au commentaire que j'ai sur votre question, ce serait également génial.
tmesser
1
@ChrisDevine Oui, je dis que je l'ai mis dans votre question donc ce n'est plus nécessaire ici.
tmesser
12

Basé sur la solution de @ LB, le code (tapé Objectplutôt que Anonymous) VB est

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

Je dois mentionner que cela est rapide et utile pour construire du contenu d'appel HTTP où le type n'est pas requis. Et utiliser Objectplutôt que Anonymoussignifie que vous pouvez maintenir Option Strict Ondans votre environnement Visual Studio - je déteste désactiver cela.

SteveCinq
la source
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
        }
Kanad Mehta
la source
3

Pour trouver le bon chemin que j'utilise

   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 utilise le Path.PathSeparator et il vérifie si le premier chemin a déjà un séparateur à la fin afin de ne pas dupliquer les séparateurs. De plus, il vérifie si les éléments de chemin à combiner ont des caractères non valides.

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

kuzdu
la source
2
Meilleure façon de trouver le chemin absolu quelle que soit l'application: stackoverflow.com/questions/15653921/get-current-folder-path/…
user3326078
3

Pour toute analyse JSON, utilisez le site Web http://json2csharp.com/ (le plus simple) pour convertir votre JSON en classe C # pour désérialiser votre JSON en objet 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; }        
 }

Utilisez ensuite JavaScriptSerializer (de System.Web.Script.Serialization), au cas où vous ne voudriez pas de DLL tierce comme newtonsoft.

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

Ensuite, vous pouvez obtenir votre objet avec Items.name ou Items.Url etc.

shailesh gavathe
la source
3

Cela peut également être fait de la manière suivante:

JObject data = JObject.Parse(File.ReadAllText(MyFilePath));
Adrita Sharma
la source