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.


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

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 .


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ć.


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

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


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.


3

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

JObject data = JObject.Parse(File.ReadAllText(MyFilePath));
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.