Przeczytaj i parsuj plik Json w C #

239

Najlepszą część dwóch dni spędziłem na „grzebaniu” w próbkach kodu itp., Próbując odczytać bardzo duży plik JSON w tablicy w języku c #, aby później móc go podzielić na tablicę 2D w celu przetworzenia.

Problem, który miałem, polegał na tym, że nie mogłem znaleźć przykładów ludzi wykonujących to, co próbowałem. Oznaczało to, że po prostu trochę edytowałem kod, mając nadzieję na najlepsze.

Udało mi się uzyskać coś, co:

  • Odczyt pliku Brakuje nagłówków i odczytuje tylko wartości do tablicy.
  • Umieść określoną liczbę wartości w każdym wierszu tablicy. (Więc mogłem później podzielić go na tablicę 2d)

Dokonano tego za pomocą poniższego kodu, ale powoduje on awarię programu po wprowadzeniu kilku wierszy do tablicy. Może to mieć związek z rozmiarem pliku.

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

Fragment kodu JSON, z którym pracuję, to:

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

Potrzebuję wartości z tego JSON. Na przykład potrzebuję „3.54”, ale nie chcę, aby drukował „vcc”.

Mam nadzieję, że ktoś pokaże mi, jak odczytać plik JSON i wyodrębnić tylko potrzebne dane i umieścić je w tablicy lub coś, czego mogę użyć do późniejszego umieszczenia w tablicy.

Chris Devine
źródło
1
Jaki wyjątek zgłasza Twój program, gdy ulega awarii?
tmesser
1
Czy to odpowiada na twoje pytanie? Jak mogę przeanalizować JSON z C #?
Heretic Monkey

Odpowiedzi:

483

Co powiesz na ułatwienie korzystania z 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;
}

Możesz nawet uzyskać wartości dynamicsojusznika bez deklarowania Itemklasy.

dynamic array = JsonConvert.DeserializeObject(json);
foreach(var item in array)
{
    Console.WriteLine("{0} {1}", item.temp, item.vcc);
}
FUNT
źródło
1
@ChrisDevine Mam nadzieję, że nie umieściłeś ścieżki jako json. Musi to być zawartość twojego pliku.
LB
4
StreamReader ( "file.json") potrzebuje strumień nie ciąg
VG
13
W C # DotNet Core użyj: using (StreamReader r = File.OpenText ("file.json"))
Fred
20
Dla osób, które nie lubią czytać innych odpowiedzi, zrozumieją jedno: to rozwiązanie wymaga pakietu Json.net (Newtonsoft.Json)
Tydaeus
1
Skoro i StreamReadertak masz , lepiej byłoby dokonać deserializacji bezpośrednio ze strumienia za pomocą, JsonTextReaderjak pokazano w Czy Json.NET może serializować / deserializować do / ze strumienia? . To r.ReadToEnd()nie jest potrzebne.
dbc
43

Robienie tego samemu jest okropnym pomysłem. Użyj Json.NET . To rozwiązało problem lepiej niż większość programistów, gdyby mieli całe miesiące pracy nad nim. Jeśli chodzi o twoje specyficzne potrzeby, parsowanie w tablice i tym podobne, sprawdź dokumentację , szczególnie na JsonTextReader. Zasadniczo Json.NET obsługuje natywnie tablice JSON i parsuje je na ciągi, inty lub cokolwiek innego, co się dzieje bez pytania od ciebie. Oto bezpośredni link do podstawowych zastosowań kodu zarówno dla czytnika, jak i pisarza, dzięki czemu możesz mieć to otwarte w wolnym oknie podczas nauki z tym pracować.

To jest najlepsze: tym razem bądź leniwy i skorzystaj z biblioteki, aby na zawsze rozwiązać ten powszechny problem .

tmesser
źródło
1
Korzystam z Json.net, ale nie rozumiem, jak to działa poprawnie. kiedy czytam informacje za pomocą JsonTextReadera do pola tekstowego, dostaję każdy kawałek danych, ale także nagłówki itp. Chcę tylko vaules w nagłówkach. Próbowałem przeczytać dokumentację Json.NET, ale nie znalazłem w niej wszystkiego, co pozwalałoby mi korzystać z niej w sposób, w jaki chciałbym
Chris Devine,
@ChrisDevine „Json headers”? Masz na myśli klucze? Być może byłoby to łatwiejsze, gdybyś opublikował krótki (~ 10-15 linii) fragment kodu JSON i wskazał dokładnie to, co próbujesz wyodrębnić.
tmesser
@ChrisDevine Właśnie dodałem twój komentarz tutaj do twojego pytania, więc jeśli możesz uprzejmie usunąć komentarz powyżej tego, byłoby świetnie.
tmesser
@ChrisDevine Również, jeśli możesz odpowiedzieć na komentarz, który mam na twoje pytanie, byłoby to również niesamowite.
tmesser
1
@ChrisDevine Tak, mówię, że zadałem to pytanie, więc nie jest już konieczne.
tmesser
12

Oparty na rozwiązaniu @ LB, kod VB (wpisany jako Objectzamiast Anonymous)

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

Powinienem wspomnieć, że jest to szybkie i przydatne do tworzenia treści połączeń HTTP, w których ten typ nie jest wymagany. I Objectzamiast używać Anonymousśrodków, które możesz utrzymać Option Strict Onw środowisku Visual Studio - nie lubię tego wyłączać.

SteveCinq
źródło
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
źródło
3

Aby znaleźć właściwą ścieżkę, której używam

   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 używa Path.PathSeparator i sprawdza, czy pierwsza ścieżka ma już separator na końcu, aby nie powielała separatorów. Dodatkowo sprawdza, czy łączone elementy ścieżki mają niepoprawne znaki.

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

kuzdu
źródło
2
Lepszy sposób na znalezienie ścieżki bezwzględnej niezależnie od aplikacji: stackoverflow.com/questions/15653921/get-current-folder-path/…
user3326078
3

W przypadku dowolnej analizy JSON skorzystaj ze strony internetowej http://json2csharp.com/ (najprostszy sposób), aby przekonwertować JSON na klasę C # i przekształcić JSON w obiekt 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; }        
 }

Następnie użyj JavaScriptSerializer (z System.Web.Script.Serialization), na wypadek, gdybyś nie chciał żadnej biblioteki DLL innej firmy, takiej jak newtonsoft.

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

Następnie możesz uzyskać swój obiekt za pomocą Items.name lub Items.Url itp.

shailesh gavathe
źródło
3

Można to również zrobić w następujący sposób:

JObject data = JObject.Parse(File.ReadAllText(MyFilePath));
Adrita Sharma
źródło