C #에서 Json 파일 읽기 및 구문 분석


239

나는 이틀 동안 코드 샘플 등을 다루면서 "faffing"의 가장 큰 부분을 보냈고, 매우 큰 JSON 파일을 c #의 배열로 읽으려고 시도했다.

내가 겪고있는 문제는 내가하려는 일을하는 사람들의 예를 찾을 수 없다는 것입니다. 이것은 내가 최선을 다하기 위해 코드를 약간 편집하고 있음을 의미했습니다.

나는 다음과 같은 일을 할 수 있었다.

  • 파일을 읽습니다. 헤더를 생략하고 값을 배열로만 읽습니다.
  • 배열의 각 행에 일정량의 값을 배치하십시오. (따라서 나중에 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 2016

답변:


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 Core에서 using : (StreamReader r = File.OpenText ( "file.json"))
Fred

20
이 답변을 이해하기 위해 다른 답변을 읽는 것을 좋아하지 않는 사람들을 위해 :이 솔루션에는 Json.net 패키지 (Newtonsoft.Json)가 필요합니다
Tydaeus

1
당신이 가지고 있기 때문에 StreamReader어쨌든, 더 나은 것 사용하여 스트림에서 직접 직렬화하기 JsonTextReader와 같이 스트림에서 수행 할 수 있습니다 Json.NET 직렬화 / 역 직렬화에 /? . 은 r.ReadToEnd()필요하지 않습니다.
dbc

43

이것을 스스로하는 것은 끔찍한 생각입니다. Json.NET을 사용하십시오 . 대부분의 프로그래머가 수개월 동안 작업을했을 경우보다 더 나은 문제를 이미 해결했습니다. 특정 요구 사항에 대해서는 배열 등으로 구문 분석하면 설명서 를 특히 확인하십시오 JsonTextReader. 기본적으로 Json.NET은 기본적으로 JSON 배열을 처리하고이를 문자열, int 또는 메시지가 표시되지 않은 유형으로 구문 분석합니다. 다음 은 리더와 라이터의 기본 코드 사용법에 대한 직접 링크입니다. 따라서이 작업을 배우면서 여분의 창에서 열 수 있습니다.

이것은 최고입니다. 이번에는 게으르고 라이브러리를 사용하여이 일반적인 문제를 영원히 해결하십시오 .


1
Json.net을 사용하고 있지만 올바르게 작동하는 방식을 이해하지 못합니다. 텍스트 상자로 JsonTextReader를 사용하여 정보를 읽을 때 모든 데이터 비트뿐만 아니라 헤더도 얻습니다. 헤더에 vaules가 필요합니다. Json.NET 문서를 읽으려고했지만 원하는 방식으로 사용할 수있는 모든 것을 설명하지 못했습니다.
Chris Devine

@ChrisDevine "Json 헤더"? 키를 언급하고 있습니까? 아마도 짧은 (~ 10-15 줄)의 스 니펫을 게시하고 추출하려는 것을 정확하게 지적하면 이것이 더 쉬울 것입니다.
tmesser 2016

@ChrisDevine 방금 귀하의 질문에 귀하의 의견을 여기에 추가 했으므로이 의견 위에 친절하게 삭제할 수 있다면 좋을 것입니다.
tmesser 2016

@ChrisDevine 또한, 귀하의 질문에 대한 의견에 답할 수 있다면 멋질 것입니다.
tmesser 2016

1
@ChrisDevine 예, 귀하의 질문에 넣었으므로 더 이상 필요하지 않습니다.
tmesser

12

@LB의 솔루션을 기반으로 VB 코드는 (이 Object아닌 형식으로 Anonymous)

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

이 유형이 필요하지 않은 HTTP 호출 콘텐츠를 구성하는 데 빠르고 유용하다는 점을 언급해야합니다. 그리고 Object오히려 사용 하는 것은 Visual Studio 환경에서 Anonymous유지할 수 있다는 것을 의미합니다 Option Strict On.


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

그런 다음 newtonsoft와 같은 타사 DLL을 원하지 않는 경우 JavaScriptSerializer (System.Web.Script.Serialization의)를 사용하십시오.

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 등으로 객체를 가져올 수 있습니다.


3

다음과 같은 방법으로도 수행 할 수 있습니다.

JObject data = JObject.Parse(File.ReadAllText(MyFilePath));
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.