web-dev-qa-db-ja.com

C#でJsonファイルを読み込んで解析する

私は2日間の大部分をコードサンプルなどで「ファフィング」して、非常に大きなJSONファイルをc#の配列に読み込もうとしたので、後でそれを処理のために2dの配列に分割することができます。

私が抱えていた問題は、自分がやろうとしていたことをしている人々の例が見つからなかったことです。これは、私がコードを少しだけ編集していることを意味します。

私はなんとかうまく動くようになった。

  • ファイルを読むヘッダを見逃し、値を配列に読み込むだけです。
  • 配列の各行に一定量の値を配置します。 (それで、後でそれを2次元配列に分割することができます)

これは以下のコードで行われましたが、数行を配列に入力した後にプログラムをクラッシュさせます。これはファイルサイズと関係があるかもしれません。

// 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ファイルを読み込み、必要なデータのみを抽出してそれを配列に格納する方法、または後で配列に格納できるようにする方法を他の人に教えてもらえればと思います。

173
Chris Devine

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クラスを宣言せずにItemallyの値を取得することもできます。

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

自分でやるのはひどい考えです。 Json.NET を使用してください。彼らがそれに取り組むために数ヶ月の終わりを与えられたならば、それはすでにほとんどのプログラマーができるよりもよく問題を解決しました。あなたが必要としていること、配列への解析などについては、 documentation 、特にJsonTextReaderをチェックしてください。基本的に、Json.NETはJSON配列をネイティブに処理し、それらを文字列、整数、またはタイプを問わずに入力したものに解析します。 ここ は、読者と作家の両方の基本的なコード使用法への直接リンクです。そのため、これを使用する方法を学習している間は、予備のウィンドウで開くことができます。

これは最良の方法です。今度は怠惰になり、ライブラリを使用して、この一般的な問題を解決してください 永遠に。

38
tmesser

@ L.B.の解決策に基づくと、(ObjectではなくAnonymousと入力)VB codeは

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

私は、これがタイプが必要とされないところでHTTP呼び出し内容を構築するために速くて有用であることに言及するべきです。そしてObjectではなくAnonymousを使うことはあなたのVisual Studio環境でOption Strict Onを維持できることを意味します - 私はそれをオフにするのが嫌いです。

8
SteveCinq
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
user3192640

正しい道を見つけるために

   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 を参照してください。

1
kuzdu