XUL でローカルファイルの入出力

カテゴリ: Firefox/Mozilla関係
| | コメント(0) | トラックバック(0)

長らく注力していた、XUL チュートリアル の翻訳作業が、一応完了したので、忘れかかっていた当初の目的を実現するべく、とりあえずは例題レベルから再開したいと思います。

単なる要素の確認は、チュートリアルの例を表示すれば足りるので、XUL に言及しているサイトを Google で検索したとき、チュートリアルに記述されていない事項として特に言及が多かった、ローカルファイルの入出力を試してみたいと思います。

ちなみに、 MDC では、ファイル I/O の例は Code snippets:File I/O に詳しく説明されています (英語版です)。

定番の Piro さんの XUL Tips を参考にして超簡単な XUL 版ファイルエディタを作成してみることにします。

まずは、XUL 要素から...

<toolbox>
  <toolbar id="file-toolbar">
    <toolbarbutton label="Open" oncommand="openFile();" />
    <toolbarbutton label="Save" oncommand="saveFile();" />
  </toolbar>
</toolbox>
<textbox id="edit-area" multiline="true" flex="1" />

必要最低限ということで、ツールバーに Open と Save ボタンを置いて、編集用のテキスト入力欄を置くだけです。

で、Open ボタンが押されたときにハンドラから呼ばれる openFile 関数は、以下のように作成します。

function openFile()
{
   var nsIFilePicker = Components.interfaces.nsIFilePicker;
   var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
   fp.init(window, "Open File", nsIFilePicker.modeOpen);
   var res = fp.show();
   if (res == nsIFilePicker.returnOK) {
      var file_in = Components.classes['@mozilla.org/network/file-input-stream;1'].
                        createInstance(Components.interfaces.nsIFileInputStream);
      var s_in = Components.classes['@mozilla.org/scriptableinputstream;1'].
                       createInstance(Components.interfaces.nsIScriptableInputStream);
      var tbox = document.getElementById("edit-area");
      var thefile = fp.file;
      try {
          file_in.init(thefile, 1, 0, false); // open as "read only"
          s_in.init(file_in); 
          var size = s_in.available();
          tbox.value = s_in.read(size);
          s_in.close();
          file_in.close();
      } catch(e) {
         alert(e);
      }
   }
}

ここでは、まず 「開く」「保存」ダイアログ にしたがって、 nsIFilePicker を、modeOpen で作成します。
で、nsIFilePicker.returnOK が、戻ってきた場合はコンポーネントからファイルを取得して、そのファイルを nsIFileInputStream に渡して読み込みます。
ここまでは、想定の範囲なのですが、Piro さんの例では、さらに nsIScriptableInputStream も使っています。これは何をするものか分からなかったので、XUL Planet の XPCOM リファレンス で、調べてみることにします...

どうやら、nsIFileInputStream の read メソッドは、[noscript] なのでスクリプトからは利用できず、必ず nsIScriptableInputStream でラップする必要があるみたいです。ふむふむ。

オブジェクトができたら、available でサイズを取得して、その長さ分 read して、textbox の value に突っ込めばおしまいです。

エラーは面倒なので、手抜きで catch したら、そのまんま alert に渡すようにします。

Open がうまくいったら、次は Save を作成します。

function saveFile() {
   var nsIFilePicker = Components.interfaces.nsIFilePicker;
   var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
   fp.init(window, "Save File", nsIFilePicker.modeSave);
   var res = fp.show();
   if (res == nsIFilePicker.returnOK ||
       res == nsIFilePicker.returnReplace){
      var out = Components.classes['@mozilla.org/network/file-output-stream;1'].
         createInstance(Components.interfaces.nsIFileOutputStream);
      var tbox = document.getElementById("edit-area");
      var thefile = fp.file;
      try {
         out.init(thefile, 0x2a, 0x200, false); // open as "write only"
         out.write(tbox.value, tbox.textLength);
         out.close();
      } catch(e) {
         alert(e);
      }
   }
}

こちらもやっていることは Open と基本的に変わらず、モードを出力に変更されていたり、コンポーネントが nsIFileOutputStream に変更されているだけです。

Piro さんの例では、ファイルがある場合は削除してから、新規作成していますが、これも面倒なので PR_CREATE_FILE (0x08) と、PR_TRUNCATE (0x20) も追加して、0x2a を指定することで nsIFileOutputStream でさせるようにします。

実行は、ローカルファイルのアクセスなので、マニフェストファイルで登録した、ディレクトリに置いて、chrome URL でアクセスする必要があります。

...なんかエラーがあるようですが、何が悪いのか分かりません (;_;)

調べると Firefox のデフォルトでは chrome のエラーは、JS コンソールには出力されないようです。一般利用者には、不要かもしれませんが、開発するときは不便極まりないので、設定を変更します。ついでに チュートリアルにも tip として追記しておきます。(イベントハンドラの追加)

修正して再実行します。
OK。

「Firefox/Mozilla関係」の新着

トラックバック(0)

このブログ記事を参照しているブログ一覧: XUL でローカルファイルの入出力

このブログ記事に対するトラックバックURL: http://morishoji.homelinux.net/mt/mt-tb.cgi/62

コメントする

最近のコメント


最近のコメントを表示...
Powered by Movable Type 4.01