Processing2.0が正式されました。ベータ7以降のいつかわかりませんが、JSONの読み込み書き込みがサポートされたので早速利用してみました。手軽にファイル入出力をするのに便利です。
JSONとは
人にもコンピュータも読みやすい軽量のフォーマットです。詳しくはオフィシャルのページをどうぞ
JSONの紹介
http://www.json.org/json-ja.html
このフォーマットの特徴は、
- 名前/値のペアで表記される、連想配列のような構造
- カンマで区切られたリスト(配列)のような構造
この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" ] }
- オブジェクトのクラス(JSONOnjectクラス)のインスタンス、sonオブジェクトを生成
- 年齢を追加
- 名前を追加
- 趣味のための配列クラス(JSONArrayクラス)のインスタンス、hobbyオブジェクトを生成
- 配列に趣味を追加
- 配列に趣味を追加
- sonオブジェクトに趣味(配列)を追加
- 確認のため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" ] } ]
ポイントは
- 全体を囲む配列を用意する(ここではJSONArray json)
- jsonに個人情報を追加
- saveJSONArray関数で保存
メソッド名 | 引数 | 戻り値 | 意味 |
---|---|---|---|
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から値を取り出すことができます。これらからどんどん抽出していけば良いわけです。ここで配列の長さが必要になりますが用意されています。
メソッド名 | 引数 | 戻り値 | 意味 |
---|---|---|---|
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にも対応しているようなので、簡単なネットワークソフトウェアも簡単に書けそうなところに期待します。