Прочитайте та проаналізуйте файл Json у C #


239

Я витратив найкращу частину двох днів на "фафінг" з зразками коду і т. Д., Намагаючись прочитати дуже великий файл JSON в масив c #, щоб пізніше розділити його на 2-двійний масив для обробки.

Проблема, яка була у мене, полягала в тому, що я не міг знайти прикладів того, щоб люди робили те, що я намагався зробити. Це означало, що я просто редагував код трохи сподіваючись на найкраще.

Мені вдалося налагодити щось, що допоможе:

  • Читайте файл Пропустіть заголовки і читайте лише значення у масиві.
  • Розмістіть певну кількість значень у кожному рядку масиву. (Тож я міг пізніше розділити його на 2d масив)

Це було зроблено з наведеним нижче кодом, але він завершує роботу програми після введення кількох рядків у масив. Це може бути пов'язано з розміром файлу.

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

Фрагмент JSON, з яким я працюю:

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

Мені потрібні значення з цього JSON. Наприклад, мені потрібно "3,54", але я б не хотів, щоб він надрукував "vcc".

Я сподіваюся, що хтось може мені показати, як читати файл JSON і лише витягувати потрібні мені дані та вносити їх у масив чи щось, що я можу використати, щоб згодом помістити у масив.


1
Який виняток робить ваша програма, коли вона виходить з ладу?
tmesser

1
Чи відповідає це на ваше запитання? Як я можу розібрати JSON за допомогою C #?
Єретична мавпа

Відповіді:


483

Як щодо спрощення всіх речей з 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;
}

Ви навіть можете отримати значення dynamicсоюзника без оголошення Itemкласу.

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

1
@ChrisDevine Я сподіваюся, що ти не поставив такий шлях json. Це повинен бути вміст вашого файлу.
LB

4
StreamReader ("file.json") потрібен Stream not string
vg

13
В ядрі C # DotNet використовуйте: using (StreamReader r = File.OpenText ("file.json"))
Фред

20
Для тих, хто не любить читати інші відповіді, щоб зрозуміти цю: для цього рішення потрібен пакет Json.net (Newtonsoft.Json)
Тидей

1
Оскільки у вас все StreamReaderодно є, краще було б десеріалізувати безпосередньо з потоку, використовуючи, JsonTextReaderяк показано в Чи може Json.NET серіалізувати / десяріалізувати в / з потоку? . Це r.ReadToEnd()не потрібно.
DBC

43

Робити це самостійно - жахлива ідея. Використовуйте Json.NET . Це вже вирішило проблему краще, ніж більшість програмістів, якби їм дали місяці наприкінці працювати над нею. Що стосується ваших конкретних потреб, розбору масивів тощо, перевірте документацію , особливо на JsonTextReader. В основному, Json.NET вручну обробляє масиви JSON і аналізує їх на рядки, ints або будь-який тип, що не відбувається, не вимагаючи від вас. Ось пряме посилання на основні звички коду як для читача, так і для письменника, тож ви можете відкрити це у запасному вікні, коли ви навчитеся працювати з цим.

Це найкраще: будьте ледачим цього разу і використовуйте бібліотеку, щоб ви вирішили цю поширену проблему назавжди.


1
Я використовую Json.net, але я не розумію, як це працює правильно. коли я читаю інформацію за допомогою JsonTextReader в текстове поле, я отримую кожен біт даних, але також заголовки тощо. Я просто хочу валу в заголовках. Я спробував прочитати документацію на Json.NET, але я не знайшов, що це пояснює все, що достатньо для мене, щоб використовувати його так, як мені хотілося
Кріс Девін

@ChrisDevine "Json headers"? Ви маєте на увазі ключі? Можливо, це буде простіше, якби ви розмістили короткий (~ 10-15 рядків) фрагмент JSON і вкажете саме на те, що ви намагаєтеся витягти.
tmesser

@ChrisDevine Я щойно додав ваш коментар до вашого запитання, тож якщо ви можете люб’язно видалити коментар вище цього, це було б чудово.
tmesser

@ChrisDevine Також, якщо ви зможете відповісти на коментар, який у мене є на ваше запитання, це також було б приголомшливим.
tmesser

1
@ChrisDevine Так, я кажу, що я поставив це у вашому питанні, тому це більше не потрібно.
tmesser

12

На основі рішення @ LB код VB ( Objectа не Anonymousтип)

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

Слід зазначити, що це швидко і корисно для створення контенту HTTP-викликів там, де тип не потрібен. І використовуючи, Objectа не Anonymousзасоби, які ви можете підтримувати Option Strict Onу своєму середовищі Visual Studio - я ненавиджу це вимикати.


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

Для пошуку правильного шляху, який я використовую

   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 використовує Path.PathSeparator, і він перевіряє, чи має перший шлях в кінці роздільник, щоб не дублювати роздільники. Крім того, він перевіряє, чи мають елементи шляху для об’єднання недійсні символи.

Дивіться https://stackoverflow.com/a/32071002/4420355


2
Кращий спосіб знайти абсолютний шлях , незалежно від програми: stackoverflow.com/questions/15653921/get-current-folder-path / ...
user3326078

3

Для будь-якого з розбору JSON використовуйте веб-сайт http://json2csharp.com/ (найпростіший спосіб) для перетворення JSON в клас C #, щоб десаріалізувати ваш JSON в об'єкт 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; }        
 }

Потім використовуйте JavaScriptSerializer (від System.Web.Script.Serialization), якщо ви не хочете, щоб жодна сторона DLL, як newtonsoft.

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

Тоді ви можете отримати свій об’єкт за допомогою items.name або Items.Url тощо.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.