Đọc và phân tích một tệp Json trong C #


239

Tôi đã dành phần tốt nhất trong hai ngày để "tập trung" vào các mẫu mã, v.v., cố gắng đọc một tệp JSON rất lớn thành một mảng trong c # để sau đó tôi có thể chia nó thành một mảng 2d để xử lý.

Vấn đề tôi gặp phải là tôi không thể tìm thấy bất kỳ ví dụ nào về những người đang làm những gì tôi đang cố gắng làm. Điều này có nghĩa là tôi chỉ chỉnh sửa mã một chút hy vọng điều tốt nhất.

Tôi đã quản lý để có được một cái gì đó làm việc sẽ:

  • Đọc tệp Bỏ qua các tiêu đề và chỉ đọc các giá trị thành mảng.
  • Đặt một lượng giá trị nhất định trên mỗi dòng của một mảng. (Vì vậy, sau này tôi có thể chia nó thành một mảng 2d)

Điều này đã được thực hiện với mã bên dưới nhưng nó bị sập chương trình sau khi nhập một vài dòng vào mảng. Điều này có thể phải làm với kích thước tập tin.

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

Một đoạn của JSON tôi đang làm việc là:

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

Tôi cần các giá trị của JSON này. Ví dụ: tôi cần "3.54", nhưng tôi không muốn nó in "vcc".

Tôi hy vọng ai đó có thể chỉ cho tôi cách đọc tệp JSON và chỉ trích xuất dữ liệu tôi cần và đặt nó vào một mảng hoặc thứ gì đó mà tôi có thể sử dụng để sau đó đưa vào một mảng.


1
Chương trình của bạn ném ngoại lệ gì khi nó gặp sự cố?
tmesser

1
Điều này có trả lời câu hỏi của bạn không? Làm cách nào tôi có thể phân tích JSON bằng C #?
Khỉ Heretic

Câu trả lời:


483

Làm thế nào về việc làm cho tất cả mọi thứ dễ dàng hơn với 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;
}

Bạn thậm chí có thể nhận được các giá trị dynamicđồng minh mà không cần khai báo Itemlớp.

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

1
@ChrisDevine Tôi hy vọng bạn đã không đặt con đường như json. Nó phải là nội dung của tập tin của bạn.
LB

4
StreamReader ("file.json") cần một chuỗi không phải là chuỗi
vg

13
Trong C # DotNet Core, sử dụng: bằng cách sử dụng (StreamReader r = File.OpenText ("file.json"))
Fred

20
Đối với những người không thích đọc các câu trả lời khác để hiểu câu trả lời này: giải pháp này yêu cầu gói Json.net (Newtonsoft.Json)
Tydaeus

1
StreamReaderdù sao bạn cũng có một cách tốt hơn, nên tốt hơn là giải tuần tự hóa trực tiếp từ luồng bằng cách sử dụng JsonTextReadernhư trong Json.NET có thể tuần tự hóa / giải tuần tự hóa thành / từ một luồng không? . Điều r.ReadToEnd()này là không cần thiết.
dbc

43

Tự làm việc này là một ý tưởng khủng khiếp. Sử dụng Json.NET . Nó đã giải quyết vấn đề tốt hơn hầu hết các lập trình viên nếu họ được kết thúc nhiều tháng để làm việc với nó. Đối với nhu cầu cụ thể của bạn, phân tích cú pháp thành mảng và như vậy, hãy kiểm tra tài liệu , đặc biệt là trên JsonTextReader. Về cơ bản, Json.NET xử lý các mảng JSON nguyên bản và sẽ phân tích chúng thành các chuỗi, int hoặc bất kỳ kiểu nào xảy ra mà không cần nhắc nhở từ bạn. Đây là một liên kết trực tiếp đến các cách sử dụng mã cơ bản cho cả người đọc và người viết, vì vậy bạn có thể mở nó trong một cửa sổ dự phòng trong khi bạn đang học cách làm việc với điều này.

Điều này là tốt nhất: Hãy lười biếng lần này và sử dụng một thư viện để bạn giải quyết vấn đề phổ biến này mãi mãi.


1
Tôi đang sử dụng Json.net nhưng tôi không hiểu làm thế nào nó hoạt động chính xác. Khi tôi đọc thông tin bằng cách sử dụng JsonTextReader vào hộp văn bản, tôi nhận được mọi bit dữ liệu nhưng cũng có tiêu đề, v.v. Tôi chỉ muốn các va chạm trong các tiêu đề. Tôi đã cố đọc tài liệu Json.NET nhưng tôi không thấy nó tách ra đủ mọi thứ để tôi sử dụng nó theo cách tôi muốn
Chris Devine

@ChrisDevine "Tiêu đề Json"? Bạn đang đề cập đến các phím? Có lẽ điều này sẽ dễ dàng hơn nếu bạn đăng một đoạn JSON ngắn (~ 10-15 dòng) và chỉ ra chính xác những gì bạn đang cố gắng trích xuất.
tmesser

@ChrisDevine Tôi vừa thêm bình luận của bạn vào câu hỏi của bạn, vì vậy nếu bạn có thể vui lòng xóa bình luận ở trên bình luận này thì thật tuyệt.
tmesser

@ChrisDevine Ngoài ra, nếu bạn có thể trả lời nhận xét tôi có về câu hỏi của bạn cũng sẽ rất tuyệt vời.
tmesser

1
@ChrisDevine Vâng, tôi đang nói rằng tôi đặt nó trong câu hỏi của bạn để nó không còn cần thiết ở đây nữa.
tmesser

12

Dựa trên giải pháp của @ LB, mã VB (được nhập Objectthay vì Anonymous) là

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

Tôi nên đề cập rằng điều này nhanh chóng và hữu ích để xây dựng nội dung cuộc gọi HTTP trong đó loại không bắt buộc. Và sử dụng Objectchứ không phải Anonymouslà bạn có thể duy trì Option Strict Ontrong môi trường Visual Studio của mình - tôi ghét tắt nó đi.


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

Để tìm đúng đường tôi đang sử dụng

   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 sử dụng Path.PathSeparator và nó kiểm tra xem đường dẫn đầu tiên đã có dấu phân cách ở cuối chưa để nó không trùng lặp các dấu phân cách. Ngoài ra, nó kiểm tra xem các thành phần đường dẫn để kết hợp có ký tự không hợp lệ hay không.

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


2
Cách tốt hơn để tìm đường dẫn tuyệt đối bất kể ứng dụng: stackoverflow.com/questions/15653921/get-civerse-folder-path/
mẹo

3

Đối với bất kỳ phân tích JSON nào, hãy sử dụng trang web http://json2csharp.com/ (cách dễ nhất) để chuyển đổi JSON của bạn thành lớp C # để giải tuần tự hóa JSON của bạn thành đối tượng 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; }        
 }

Sau đó, sử dụng JavaScriptSerializer (từ System.Web.Script.Serialization), trong trường hợp bạn không muốn bất kỳ DLL bên thứ ba nào như newtonsoft.

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

Sau đó, bạn có thể nhận được đối tượng của mình với Item.name hoặc Item.Url, v.v.


3

Điều này cũng có thể được thực hiện theo cách sau:

JObject data = JObject.Parse(File.ReadAllText(MyFilePath));
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.