C#でのJsonファイルの読み取りと解析


240

私は2日間の大部分をコードサンプルなどの「扱い」に費やし、非常に大きなJSONファイルをc#の配列に読み取って、後で処理するために2d配列に分割できるようにしました。

私が抱えていた問題は、私がやろうとしていることをしている人の例を見つけることができなかったことです。これは、私がコードを少し編集していて、最高のものを期待していることを意味しました。

私はなんとか機能するものを手に入れることができました:

  • Miss outヘッダーファイルを読み取り、配列に値のみを読み取ります。
  • 配列の各行に特定の量の値を配置します。(それで、後でそれを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
これはあなたの質問に答えますか?C#でJSONを解析するにはどうすればよいですか?
異端の猿

回答:


484

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")には文字列ではなくストリームが必要
vg

13
C#DotNet Coreでは、次を使用します。using(StreamReader r = File.OpenText( "file.json"))
Fred

20
これを理解するために他の回答を読みたくない人のために:このソリューションにはJson.netパッケージ(Newtonsoft.Json)が必要
Tydaeus

1
StreamReaderとにかくあなたが持っているので、Json.NETが直列化/非直列化/ストリームにJsonTextReader示すように使用してストリームから直接非直列化する方が良いでしょうか?r.ReadToEnd()必要とされていません。
dbc

43

これを自分で行うのはひどい考えです。Json.NETを使用します。それは彼らがそれに取り組むために何ヶ月も与えられた場合、ほとんどのプログラマーがすることができるよりも問題をすでによりよく解決しました。特定のニーズ、配列などへの解析については、特にでドキュメントを確認してくださいJsonTextReader。基本的に、Json.NETはJSON配列をネイティブに処理し、文字列、int、またはタイプが偶然に何であれ、ユーザーからのプロンプトなしにそれらを解析します。 これは、リーダーとライターの両方の基本的なコードの使用法への直接リンクです。そのため、これを扱うことを学んでいる間、それを予備のウィンドウで開くことができます。

これは最高です。今回は怠惰でライブラリを使用して、この一般的な問題を永久に解決します。


1
私はJson.netを使用していますが、Json.netが正しく機能する方法がわかりません。JsonTextReaderを使用してテキストボックスに情報を読み込むと、データのすべてのビットだけでなくヘッダーなども取得します。ヘッダーの値が欲しいだけです。私はJson.NETのドキュメントを読み込もうとしましたが、私が思い通りに使用するのに十分なすべてを説明しているとはわかりませんでした
Chris Devine

@ChrisDevine「Jsonヘッダー」?鍵のことですか?おそらく、短い(10行から15行まで)JSONのスニペットを投稿し、抽出しようとしているものを正確にポイントすると、これはより簡単になるでしょう。
tmesser

@ChrisDevine私はここにあなたのコメントをあなたの質問に追加しましたので、このコメントの上にあるコメントを親切に削除していただければ素晴らしいと思います。
tmesser

@ChrisDevineまた、あなたの質問に対するコメントに答えてもらえれば、それも素晴らしいことです。
tmesser

1
@ChrisDevineはい、私はあなたの質問にそれを入れたと言っていますので、ここではもう必要ありません。
tmesser

12

@LBのソリューションに基づいて、(Objectではなくとして入力されたAnonymous)VBコードは

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

これは、タイプが必要ないHTTP呼び出しコンテンツを構築するのに迅速かつ便利であることを述べておかなければなりません。そして、使用するとObjectいうよりAnonymousOption 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解析については、Webサイト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.