Lesen und analysieren Sie eine Json-Datei in C #

239

Ich habe den größten Teil von zwei Tagen damit verbracht, mich mit Codebeispielen usw. zu "beschäftigen" und zu versuchen, eine sehr große JSON-Datei in ein Array in c # zu lesen, damit ich sie später zur Verarbeitung in ein 2D-Array aufteilen kann.

Das Problem, das ich hatte, war, dass ich keine Beispiele für Leute finden konnte, die das taten, was ich versuchte. Dies bedeutete, dass ich nur ein wenig Code bearbeitete und auf das Beste hoffte.

Ich habe es geschafft, etwas zum Laufen zu bringen, das:

  • Lesen Sie die Datei. Verpassen Sie Header und lesen Sie nur Werte in das Array.
  • Platzieren Sie eine bestimmte Anzahl von Werten in jeder Zeile eines Arrays. (Also könnte ich es später aufteilen und in ein 2D-Array aufteilen)

Dies wurde mit dem folgenden Code durchgeführt, stürzt jedoch das Programm ab, nachdem einige Zeilen in das Array eingegeben wurden. Dies hängt möglicherweise mit der Dateigröße zusammen.

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

Ein Ausschnitt aus dem JSON, mit dem ich arbeite, ist:

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

Ich brauche die Werte aus diesem JSON. Zum Beispiel brauche ich "3.54", aber ich möchte nicht, dass es das "vcc" druckt.

Ich hoffe, jemand kann mir zeigen, wie man eine JSON-Datei einliest und nur die benötigten Daten extrahiert und in ein Array oder etwas, das ich später in ein Array einfügen kann, einfügt.

Chris Devine
quelle
1
Welche Ausnahme löst Ihr Programm aus, wenn es abstürzt?
Messer
1
Beantwortet das deine Frage? Wie kann ich JSON mit C # analysieren?
Heretic Monkey

Antworten:

482

Wie wäre es, wenn Sie mit Json.NET alles einfacher machen ? ?

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

Sie können die Werte sogar dynamicverbünden, ohne die ItemKlasse zu deklarieren .

dynamic array = JsonConvert.DeserializeObject(json);
foreach(var item in array)
{
    Console.WriteLine("{0} {1}", item.temp, item.vcc);
}
PFUND
quelle
1
@ ChrisDevine Ich hoffe du hast den Pfad nicht als gesetzt json. Es muss der Inhalt Ihrer Datei sein.
LB
4
StreamReader ("file.json") benötigt einen Stream ohne String
vg
13
Verwenden Sie in C # DotNet Core: using (StreamReader r = File.OpenText ("file.json"))
Fred
20
Für die Leute, die die anderen Antworten nicht gerne lesen, um diese zu verstehen: Diese Lösung erfordert das Json.net-Paket (Newtonsoft.Json)
Tydaeus
1
Da Sie StreamReadersowieso eine haben, ist es besser, direkt aus dem Stream zu deserialisieren, indem Sie JsonTextReaderwie in Kann Json.NET zeigen / deserialisieren zu / von einem Stream zeigen? . Das r.ReadToEnd()wird nicht benötigt.
dbc
43

Dies selbst zu tun ist eine schreckliche Idee. Verwenden Sie Json.NET . Es hat das Problem bereits besser gelöst als die meisten Programmierer, wenn sie monatelang Zeit hätten, daran zu arbeiten. Informationen zu Ihren spezifischen Anforderungen, zum Parsen in Arrays usw. finden Sie in der Dokumentation , insbesondere unter JsonTextReader. Grundsätzlich verarbeitet Json.NET JSON-Arrays nativ und analysiert sie in Zeichenfolgen, Ints oder was auch immer der Typ ist, ohne dass Sie dazu aufgefordert werden. Hier ist ein direkter Link zu den grundlegenden Code-Verwendungen für Leser und Schreiber, sodass Sie diese in einem Ersatzfenster öffnen können, während Sie lernen, damit zu arbeiten.

Dies ist das Beste: Seien Sie diesmal faul und verwenden Sie eine Bibliothek, um dieses häufig auftretende Problem zu lösen für immer .

tmesser
quelle
1
Ich benutze Json.net, aber ich verstehe nicht, wie es richtig funktioniert. Wenn ich die Informationen mit JsonTextReader in ein Textfeld lese, erhalte ich jedes Datenbit, aber auch Header usw. Ich möchte nur die Vaules in den Headern. Ich habe versucht, die Json.NET-Dokumentation zu lesen, aber ich fand nicht, dass sie alles so erklärt, dass ich sie so verwenden kann, wie ich es gerne hätte
Chris Devine,
@ ChrisDevine "Json-Header"? Beziehen Sie sich auf die Schlüssel? Vielleicht wäre dies einfacher, wenn Sie einen kurzen Ausschnitt (~ 10-15 Zeilen) von JSON veröffentlichen und genau auf das zeigen, was Sie extrahieren möchten.
Messer
@ChrisDevine Ich habe gerade Ihren Kommentar hier zu Ihrer Frage hinzugefügt. Wenn Sie also den Kommentar über diesem Kommentar löschen könnten, wäre das großartig.
Messer
@ChrisDevine Auch wenn Sie den Kommentar beantworten könnten, den ich zu Ihrer Frage habe, wäre das auch fantastisch.
Messer
1
@ChrisDevine Ja, ich sage, ich habe es in Ihre Frage gestellt, damit es hier nicht mehr notwendig ist.
Messer
12

Basierend auf der Lösung von @ LB lautet der ( Objecteher als als Anonymous) VB-Code

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

Ich sollte erwähnen, dass dies schnell und nützlich ist, um HTTP-Aufrufinhalte zu erstellen, bei denen der Typ nicht erforderlich ist. Und ich verwende es nicht, Objectsondern Anonymouskann es Option Strict Onin Ihrer Visual Studio-Umgebung beibehalten - ich hasse es, das auszuschalten.

SteveCinq
quelle
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
quelle
3

Um den richtigen Weg zu finden, benutze ich

   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 verwendet den Path.PathSeparator und prüft, ob der erste Pfad am Ende bereits ein Trennzeichen enthält, damit die Trennzeichen nicht dupliziert werden. Außerdem wird geprüft, ob die zu kombinierenden Pfadelemente ungültige Zeichen enthalten.

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

Kuzdu
quelle
2
Besserer Weg, um den absoluten Pfad unabhängig von der Anwendung zu finden: stackoverflow.com/questions/15653921/get-current-folder-path/…
user3326078
3

Verwenden Sie für die JSON-Analyse die Website http://json2csharp.com/ (am einfachsten), um Ihren JSON in eine C # -Klasse zu konvertieren und Ihren JSON in ein C # -Objekt zu deserialisieren.

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

Verwenden Sie dann den JavaScriptSerializer (aus System.Web.Script.Serialization), falls Sie keine DLL eines Drittanbieters wie newtonsoft möchten.

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

Dann können Sie Ihr Objekt mit Items.name oder Items.Url usw. erhalten.

Shailesh Gavathe
quelle
3

Dies kann auch folgendermaßen erfolgen:

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