JavaFX 1.2 のローカルストレージを試してみる

今回は、JavaFX 1.2 で使えるようになったローカルストレージを試してみます。
まずは単純なスクリプト書いて、NetBeans 上で動かしてみます。


ソースコード

package fooami;

import javafx.io.*;
import java.io.*;

/**
 * @author hide1080
 */

var storage = Storage {
    source: "storagetest.txt"
}
var resource = storage.resource;

function writeToStrage() {
    var os = resource.openOutputStream(false);
    var writer = new PrintWriter(os);
    writer.println("JavaFX 1.2 が便利になったよ!");
    writer.close();
}
function readToStrage() {
    var is = resource.openInputStream();
    var reader = new BufferedReader(new InputStreamReader(is));
    var line: Object;
    while ((line = reader.readLine()) != null) {
        println(line);
    }
    reader.close();
}
writeToStrage();
readToStrage();


実行結果(コンソール):

...
JavaFX 1.2 が便利になったよ!
...


僕の環境は Windows VISTA なのですが、書き込まれたデータは以下の場所に保存されていました。
場所: C:\Users\hide1080\Sun\JavaFX\Deployment\storage\muffin
作成されたファイルの名前は、プログラムの中から指定した名前(今回は storagetest.txt)とは別の名前になっていました。当然アプリやドメインの違いなどによって変わってくるんだと思います。
名前: 21edb95e-17e386c2
Storage クラスは、他にもデータを削除する clear() や clearAll() メソッドや、現在のアプリケーションからアクセス可能なストレージ上のリソース名のリストを取得する list() メソッドがあります。


では、今度はアプレットにして外に配置して実行してみます。


Appet のソースコード

/*
 * LocalStorageExample.fx
 *
 * Created on 2009/06/02, 19:04:57
 */

package fooami;

import java.io.*;

import javafx.io.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.Tile;
import javafx.scene.text.Font;
import javafx.stage.*;

/**
 * @author hide1080
 */

var storage = Storage {
    source: "storagetest.txt"
}
var resource = storage.resource;

function writeToStrage() {
    var os = resource.openOutputStream(false);
    var writer = new PrintWriter(os);
    writer.println(text);
    writer.close();
}
function readToStrage() {
    var is = resource.openInputStream();
    var reader = new BufferedReader(new InputStreamReader(is));
    var line: Object;
    var buff: String;
    while ((line = reader.readLine()) != null) {
        buff += "{line}\n";
    }
    Alert.inform(buff);
    reader.close();
}

var text: String = "hoge";
Stage {
    title : "MyApp"
    scene: Scene {
        width: 180
        height: 100
        content: [
            Tile {
                vertical: true
                vgap: 10
                columns: 1
                rows: 3
                content: [
                    TextBox {
                        text: bind text with inverse
                        columns: 20
                        selectOnFocus: true
                    }
                    Button {
                        text: "書き込む"
                        action: function() {
                            writeToStrage();
                        }
                        font: Font{}
                    }
                    Button {
                        text: "読み込む"
                        action: function() {
                            readToStrage();
                        }
                        font: Font{}
                    }
                ]
            }
        ]
    }
}

※ Button に Font{} を指定しているのは、指定しないと日本語が文字化けしてしまうからです。バグ報告済みですが bluepapa32 さんが font を設定することによる応急処置方法を発見してくださったのでこうしています。
http://d.hatena.ne.jp/hide1080/20090531/1243793490#c1243832119


画面上にテキストボックスと「書き込む」ボタン、「読み込む」ボタンを置いてます。
「書き込む」ボタンを押すと、テキストボックスの内容をローカルストレージに保存します。
「読み込む」ボタンを押すと、ローカルストレージに保存したデータを Alert で表示します。

結果はこんな感じです。


結果:

「読み込む」ボタン押下時:


なんと、ユーザーのローカルファイルシステムにデータを読み書きするにもかかわらず、署名が要りません。
なんだかこれにすごく衝撃を感じてしまいました。
ユーザーに不信感を感じさせたり、あまり理解できていないユーザーに判断を委ねなくて良いんです。
そのかわりにセキュリティ面の安全性は Java (or JavaFX) がしっかり補ってくれるのでしょう。
う〜ん、すごく巨大なデータを書き込もうとする悪意のあるマルアプリケーションの振る舞いからはどのように保護されるんでしょうね。リリースノートが公開されたら説明があるかもしれませんが、なければ暇を見つけて試してみたいと思います。


とまあ、こんな感じです。JavaFX がますます楽しくなってきましたよ。
JavaFX 1.2 で使えるようになった、ローカルストレージのお話でした。


お試しアプレット
http://www7b.biglobe.ne.jp/~fooami/demo/localstrageexample/LocalStorageExample.html


追記:
2箇所訂正しました。
アプレットのサンプルコードに storage.clearAll(); が入ってしまってたので削除しました。これが入っていると、2回目以降の実行時に前回の保存データが削除されて読めません。
Alert.confirm(buff); は、確認ボタンが不要の為、Alert.inform(buff); に変更しました。結果のイメージは以前のままです。

2009/07/03 追記:
サンプルソースコードの変数 line の型を String から Object に変更しました。理由は 2009/07/03 のエントリを参照してください。