Writing textual data
出典: MDC
この記事では、国際化を考慮しつつ、テキストデータをストリーム、ファイル、ソケットに書き込む方法を説明します。
警告:この記事では仕様が未確定のインタフェースを使用しています。これらのインタフェースは新しい Mozilla では変更になる可能性があり、そのときはコードが機能しなくなるかもしれません。
テキストデータを出力ストリームやファイルに書き込むときは、文字エンコーディングを選択する必要があります。
UTF-8、UTF-16、UTF-32 といった文字エンコーディングは、その他が全レパートリの一部しか表せないのに対して、「すべての」文字(Unicode の全レパートリ)を表すことができます。
そのファイルがアプリケーションや拡張機能自身からしか読み込まれないのであれば UTF-8 の使用は最良の選択です。すべての文字を表すことができ、ASCII 文字も効率的に表されます。
目次 |
[編集] ストリームへの書き込み
Gecko 1.8 (SeaMonkey 1.0、Firefox 1.5) では nsIConverterOutputStream を使うことができます。
var charset = "UTF-8"; // Mozilla がサポートしている文字エンコーディング名なら何でも指定可
var os = Components.classes["@mozilla.org/intl/converter-output-stream;1"]
.createInstance(Components.interfaces.nsIConverterOutputStream);
// ここでは fos は書き込み先にしたい nsIOutputStream であると仮定
os.init(fos, charset, 0, 0x0000);
os.writeString("Umlaute: \u00FC \u00E4\n");
os.writeString("Hebrew: \u05D0 \u05D1\n");
// etc.
os.close();
writeString を使ったほうが JavaScript のコードがシンプルになりますが、write 関数を使用して文字配列を書き込むこともできます。
この例では 0 を第 3 引数にしています。これによってバッファリングを無効にしています(注意:コンバータストリームの実装はバッファリングをサポートしていない可能性があります)。0 にするとストリームに即座にデータを書き込むことになります。しかし、4096 などにしたほうがパフォーマンスは向上します。
[編集] 未サポートの文字
選択した文字エンコーディングがサポートしていない文字を使用したことでどんな問題が生じるかを指定できます。init の最後の引数がそれを指定しています。0x0000 は未サポートの文字を書き込むと例外を投げ(NS_ERROR_LOSS_OF_SIGNIFICANT_DATA というエラーコード)、データを書き込まないということを意味します。
このような場合に代わりの文字を書き込むときは 0x00 の代わりに文字を指定してください。
os.init(fos, charset, 0, "?".charCodeAt(0));
もちろん、この例での "?" を別のどんな文字と置き換えてもかまいません。U+ABCD のようなどんな unicode 文字も 0xABCD のように直接指定することもできます。
注意:置換する文字が選択した文字エンコーディングでサポートされていない場合、未サポートの文字を書き込もうとし、NS_ERROR_LOSS_OF_SIGNIFICANT_DATA とともに失敗します。
[編集] Gecko 1.8 以前のバージョン
Firefox 1.0.x や Mozilla 1.7.x 以前のバージョンでは nsIConverterOutputStream をサポートしていません。
JavaScript から利用可能な代替策はヌルの埋め込みを使っている文字エンコーディング(UTF-16 や UTF-32 など)をサポートしていません。手動で nsIScriptableUnicodeConverter を使って書き込みたい文字列をバイト列に変換し、それをストリームに書き込むことになります。
以下がその例です。
// まずコンバータの取得と初期化
var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
.createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
converter.charset = /* 使いたい文字エンコーディング:この例では UTF-8 */ "UTF-8";
そして変換し、ストリームに書き込みます。
// このコードでは os は nsIOutputStream、 // your_string は書き込みたい文字列と仮定 var chunk = converter.ConvertFromUnicode(your_string); os.write(chunk, chunk.length); // 必要に応じ、他の文字列に対しても繰り返し
最後に、Finish を呼び出し、データをストリームに書き込む必要があります。
これを必要とする文字エンコーディングはあまりありませんが、これが必要な文字エンコーディングを扱う際に、この作業はきちんとした出力を得るために重要なことなのです。
var fin = converter.Finish(); if (fin.length > 0) os.write(fin, fin.length); os.close();
[編集] ストリームへの文字列の変換
文字列をストリームに変換したほうが便利な場合があります。たとえば nsIUploadChannel を使ってアップロードする場合です。
この例では Gecko 1.8 (Firefox 1.5、SeaMonkey 1.0) が必要です。
nsIScriptableUnicodeConverter にはそのためのシンプルなメソッドがあります。
// まずコンバータの取得と初期化
var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
.createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
converter.charset = /* 使いたい文字エンコーディング:この例では UTF-8 */ "UTF-8";
// そして文字列を nsIInputStream に変換
var stream = converter.convertToInputStream("A string with non-ASCII characters: \u00FC \u05D0\n");
// ストリームを nsIInputStream として使えるようになった