[Processing] JSONの読み込み書き込み

Processing2.0が正式されました。ベータ7以降のいつかわかりませんが、JSONの読み込み書き込みがサポートされたので早速利用してみました。手軽にファイル入出力をするのに便利です。

JSONとは

人にもコンピュータも読みやすい軽量のフォーマットです。詳しくはオフィシャルのページをどうぞ

http://www.json.org/json-ja.html

JSONの紹介
http://www.json.org/json-ja.html

このフォーマットの特徴は、

  1. 名前/値のペアで表記される、連想配列のような構造
  2. カンマで区切られたリスト(配列)のような構造

この2つで表現できるところです。

オブジェクト

オブジェクトは中括弧({ , })で囲み、中の要素は文字列/値で表現します。複数の要素を利用する場合は、カンマで区切り、続けて記述します。

{
	文字列:値,
	文字列:値,
	.
	.
	文字列:値
}

配列

配列は大括弧([ , ])で囲み、中の要素を値の連続(0個以上)で表現します。複数の要素を利用する場合は、カンマで区切り、続けて記述します。

[ 値, 値, ..., 値]

値は以下の7種類です

  • 文字列
  • 数値
  • オブジェクト
  • 配列
  • true
  • false
  • null

文字列は2重引用符(“)で囲まれます。

構造化する

値はオブジェクトや配列も含まれていますので、構造化することができます。今回は以下のJSONファイルを読み込み・書き込みをします。

[
	{ 
		"name":"son",
		"age":21,
		"hobby":["baseball","car"]
	},
	{ 
		"name":"daughter",
		"age":18,
		"hobby":["shopping","tv game"]
	},
	{ 
		"name":"daddy",
		"age":42,
		"hobby":["car","fishing"]
	}
]

このJSONファイルの構造は、個人情報をオブジェクト単位として複数人分用意し配列としています。個人情報は、名前・年齢・趣味があります。名前は文字列、年齢は数値、趣味は複数あるので配列としています。配列の中は文字列としています。

注意

JSONファイルの利用において、setup〜drawを利用したアニメーションのモードでないと実行できませんでした。今回の処理は全てsetup関数内に記述しています。

ProcessingでJSONファイルを書き込む

JSONファイルを書き込む方法は、オブジェクトを書き込むsaveJSONObject関数と、配列を書き込むsaveJSONArray関数が用意されています。

関数名 引数 意味
saveJSONObject JSONObject, ファイルパス JSONオブジェクトを書き込む
saveJSONArray JSONArray, ファイルパス JSON配列を書き込む

この関数を利用することで保存することができます。今回作成するJSONファイル(person.json)は配列の中に格納されているので、saveJSONArray関数を利用します。

sketchの作成

保存するパス中に日本語が入らないように注意し、適当な名前でsketchを保存します。今回は”saveJSON”として作成しました。

JSONオブジェクト作成

JSONオブジェクトのクラス(JSONObjectクラス)があります。このクラスを生成し、メソッドで名前/値を追加していきます。また、JSONObjectは追加した名前で値を取得するメソッドも用意されています。

オブジェクトへの追加メソッド
メソッド名 引数 意味
setString 名前, 文字列 名前/文字列を追加
setInt 名前, 整数 名前/整数を追加
setFloat 名前, 実数 名前/実数を追加
setJSONObject 名前, JSONObject 名前/オブジェクトを追加
setJSONArray 名前y, JSONArray 名前/配列を追加
オブジェクトから取得メソッド
メソッド名 引数 戻り値 意味
getString 名前 文字列 名前から文字列を取得
getInt 名前 整数 名前から整数を取得
getFloat 名前 実数 名前から実数を取得
getJSONObject 名前 JSONObjecttd 名前からオブジェクトを取得
getJSONArray 名前 JSONArraytd 名前から配列を取得

JSON配列作成

JSONの配列クラス(JSONArrayクラス)が用意されています。このクラスを生成し、値を追加します。追加の方法は、配列の添字を指定して挿入するか、末尾へ追加するメソッドが用意されています。

配列への追加メソッド
メソッド名 引数 意味
setString 添字, 文字列 文字列を[添字]番目に追加
setInt 添字, 整数 整数を[添字]番目に追加
setFloat 添字, 実数 実数を[添字]番目に追加
setJSONObject 添字, JSONObject オブジェクトを[添字]番目に追加
setJSONArray 添字, JSONArray 配列を[添字]番目に追加
append 追加要素 引数の型は格納できる型すべて。配列の末尾に追加
配列から取得メソッド
メソッド名 引数 戻り値 意味
getString 添字 <文字列/td>

添字番目の文字列を取得
getInt 添字 整数 添字番目の整数を取得
getFloat 添字 実数 添字番目の実数を取得
getJSONObject 添字 JSONObjecttd 添字番目のオブジェクトを取得
getJSONArray 添字 JSONArraytd 添字番目の配列を取得

個人のオブジェクトを作成

目標のJSONファイルは個人情報の連続なので、まずは個人情報のオブジェクトを作成します。まずは、sonさんの情報を作成します。

	JSONArray hobby;
	// son
	JSONObject son = new JSONObject();
	son.setInt("age",21);
	son.setString("name","son");
	hobby = new JSONArray();
	hobby.append("baseball");
	hobby.append("car");
	son.setJSONArray("hobby",hobby);
	println(son);
{
  "name": "son",
  "age": 21,
  "hobby": [
    "baseball",
    "car"
  ]
}
  1. オブジェクトのクラス(JSONOnjectクラス)のインスタンス、sonオブジェクトを生成
  2. 年齢を追加
  3. 名前を追加
  4. 趣味のための配列クラス(JSONArrayクラス)のインスタンス、hobbyオブジェクトを生成
  5. 配列に趣味を追加
  6. 配列に趣味を追加
  7. sonオブジェクトに趣味(配列)を追加
  8. 確認のためsonオブジェクトを表示

良い感じでオブジェクトが作成できました。このオブジェクトを人数用意すれば良いわけです。

出力用JSONオブジェクトを完成、ファイルに書き込む

個人用のオブジェクトを人数分用意します。これらを配列にして書込して終了です。

void setup(){
	JSONArray json = new JSONArray();
	JSONArray hobby;

	// son
	JSONObject son = new JSONObject();
	son.setInt("age",21);
	son.setString("name","son");
	hobby = new JSONArray();
	hobby.append("baseball");
	hobby.append("car");
	son.setJSONArray("hobby",hobby);

	// daughter
	JSONObject daughter = new JSONObject();
	daughter.setInt("age",18);
	daughter.setString("name","daughter");
	hobby = new JSONArray();
	hobby.append("shopping");
	hobby.append("tv game");
	daughter.setJSONArray("hobby",hobby);

	// daddy
	JSONObject  daddy = new JSONObject();
	daddy.setInt("age",42);
	daddy.setString("name","daddy");
	hobby = new JSONArray();
	hobby.append("car");
	hobby.append("fishing");
	daddy.setJSONArray("hobby",hobby);

	// 配列に個人情報オブジェクトを追加
	json.append(son);
	json.append(daughter);
	json.append(daddy);
	// data/person.json に保存
	saveJSONArray(json,"data/person.json");
}
[
  {
    "name": "son",
    "age": 21,
    "hobby": [
      "baseball",
      "car"
    ]
  },
  {
    "name": "daughter",
    "age": 18,
    "hobby": [
      "shopping",
      "tv game"
    ]
  },
  {
    "name": "daddy",
    "age": 42,
    "hobby": [
      "car",
      "fishing"
    ]
  }
]

ポイントは

  1. 全体を囲む配列を用意する(ここではJSONArray json)
  2. jsonに個人情報を追加
  3. saveJSONArray関数で保存
JSONオブジェクト・配列書き込み関数
メソッド名 引数 戻り値 意味
saveJSONObject JSONObject, ファイルパス 成功(true)・失敗(false) オブジェクトを指定されたファイルパスに保存
saveJSONArray JSONArray, ファイルパス 成功(true)・失敗(false) 配列を指定されたファイルパスに保存

ここで、ファイルパスはsketchのフォルダを起点となります。今回はdata/person.jsonなので、sketchの中のdataディレクトリがあり、その中にperson.jsonというテキストファイルが書き込まれます。もしかしたら、dataディレクトリがなければ作らないと書き込みされないかもしれません。

ProcessingでJSONファイルの読み込み

jsonファイルを読み込み方法として、ファイルからオブジェクトを読み込むloadJSONObject関数と、ファイルから配列を読み込むloadJSONArray関数が用意されています。今回のJSONファイルは配列から始まるので、loadJSONArray関数を利用します

関数名 引数 戻り値 意味
loadJSONObject ファイルパス(もしくはURL) JSONObject JSONファイルからオブジェクト読み込み
loadJSONArray ファイルパス(もしくはURL) JSONArray JSONファイルから配列読み込み

読み込むファイルは、sketchのdataディレクトリを起点にしますので、指定に注意をしてください。

sketchの作成

保存するパス中に日本語が入らないように注意し、適当な名前でsketchを保存します。今回は”loadJSON”として作成しました。前述したperson.jsonをsketchのdataディレクトリの中にコピーしました。

読み込み例

前述の書き込みでも書きましたが、JSONObjectやJSONArrayから値を取り出すことができます。これらからどんどん抽出していけば良いわけです。ここで配列の長さが必要になりますが用意されています。

JSONArrayクラスのメソッド
メソッド名 引数 戻り値 意味
size なし 配列の長さ JSONArrayのオブジェクトの長さを返す

配列長が取得できれば繰り返し取得すれば良いわけです。以下のコードが読み込み例です。

void setup(){
  //ファイルから配列を読み込み
  JSONArray json = loadJSONArray("person.json");
  //配列の中身を順繰り処理
  for(int i = 0; i < json.size(); i++){
    // 個人情報オブジェクトを取得
    JSONObject person = json.getJSONObject(i);
    // 個人情報のhobbyから趣味の配列を取得
    JSONArray hobby = person.getJSONArray("hobby");
    // 名前、年齢を表示
    println("名前:"+person.getString("name")+",年齢:"+person.getInt("age"));
    // 趣味を順繰り表示
    for(int j=0;j<hobby.size();j++){
      print(hobby.getString(j)+" ");
    }
    println(""); // 改行
  }
}
名前:son,年齢:21
baseball car 
名前:daughter,年齢:18
shopping tv game 
名前:daddy,年齢:42
car fishing 

このように、get****メソッドを利用して値を取得していきます。この工程はほぼ書き込みの逆ですので、難しくはないと思います。しかし、順番(というか構造)を間違えないように注意が必要です。

おわりに

Processing2が正式リリースになったのを記念してJSONの読み込み&書き込みを調べてみました。やっぱり色々便利ですね。他の言語でも様々なライブラリで読み書きできますので、やりとりも楽々なのが嬉しいです。また、読み込み関数はURLにも対応しているようなので、簡単なネットワークソフトウェアも簡単に書けそうなところに期待します。

関連

[Unity][MiniJSON]JSONデータを読み込む

コメントを残す

メールアドレスが公開されることはありません。