blob: f678277b6366886263222dfa919134f936b88277 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
---
title: Writing textual data
slug: Archive/Mozilla/Writing_textual_data
tags:
- Add-ons
- Extensions
- Internationalization
translation_of: Archive/Mozilla/Writing_textual_data
---
<p> </p><p>この記事では、国際化を考慮しつつ、テキストデータをストリーム、ファイル、ソケットに書き込む方法を説明します。
</p>
<div class="warning">
<p><i>警告</i>:この記事では仕様が未確定のインタフェースを使用しています。これらのインタフェースは新しい Mozilla では変更になる可能性があり、そのときはコードが機能しなくなるかもしれません。
</p>
</div>
<p>テキストデータを出力ストリームやファイルに書き込むときは、文字エンコーディングを選択する必要があります。
</p><p>UTF-8、UTF-16、UTF-32 といった文字エンコーディングは、その他が全レパートリの一部しか表せないのに対して、「すべての」文字(Unicode の全レパートリ)を表すことができます。
</p><p>そのファイルがアプリケーションや拡張機能自身からしか読み込まれないのであれば UTF-8 の使用は最良の選択です。すべての文字を表すことができ、ASCII 文字も効率的に表されます。
</p>
<h3 id=".E3.82.B9.E3.83.88.E3.83.AA.E3.83.BC.E3.83.A0.E3.81.B8.E3.81.AE.E6.9B.B8.E3.81.8D.E8.BE.BC.E3.81.BF" name=".E3.82.B9.E3.83.88.E3.83.AA.E3.83.BC.E3.83.A0.E3.81.B8.E3.81.AE.E6.9B.B8.E3.81.8D.E8.BE.BC.E3.81.BF"> ストリームへの書き込み </h3>
<p>Gecko 1.8 (SeaMonkey 1.0、Firefox 1.5) では <code><a href="/ja/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIConverterOutputStream" title="">nsIConverterOutputStream</a></code> を使うことができます。
</p>
<pre class="eval">var charset = "UTF-8"; // Mozilla がサポートしている文字エンコーディング名なら何でも指定可
var os = Components.classes["@mozilla.org/intl/converter-output-stream;1"]
.createInstance(Components.interfaces.nsIConverterOutputStream);
// ここでは fos は書き込み先にしたい <code><a href="/ja/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIOutputStream" title="">nsIOutputStream</a></code> であると仮定
os.init(fos, charset, 0, 0x0000);
os.writeString("Umlaute: \u00FC \u00E4\n");
os.writeString("Hebrew: \u05D0 \u05D1\n");
// etc.
os.close();
</pre>
<p><code>writeString</code> を使ったほうが JavaScript のコードがシンプルになりますが、<code>write</code> 関数を使用して文字配列を書き込むこともできます。
</p><p>この例では 0 を第 3 引数にしています。これによってバッファリングを無効にしています(注意:コンバータストリームの実装はバッファリングをサポートしていない可能性があります)。0 にするとストリームに即座にデータを書き込むことになります。しかし、4096 などにしたほうがパフォーマンスは向上します。
</p>
<h4 id=".E6.9C.AA.E3.82.B5.E3.83.9D.E3.83.BC.E3.83.88.E3.81.AE.E6.96.87.E5.AD.97" name=".E6.9C.AA.E3.82.B5.E3.83.9D.E3.83.BC.E3.83.88.E3.81.AE.E6.96.87.E5.AD.97"> 未サポートの文字 </h4>
<p>選択した文字エンコーディングがサポートしていない文字を使用したことでどんな問題が生じるかを指定できます。init の最後の引数がそれを指定しています。0x0000 は未サポートの文字を書き込むと例外を投げ(<a href="ja/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA">NS_ERROR_LOSS_OF_SIGNIFICANT_DATA</a> というエラーコード)、データを書き込まないということを意味します。
</p><p>このような場合に代わりの文字を書き込むときは 0x00 の代わりに文字を指定してください。
</p>
<pre class="eval">os.init(fos, charset, 0, "?".charCodeAt(0));
</pre>
<p>もちろん、この例での <code>"?"</code> を別のどんな文字と置き換えてもかまいません。U+ABCD のようなどんな unicode 文字も 0xABCD のように直接指定することもできます。
</p><p><i>注意</i>:置換する文字が選択した文字エンコーディングでサポートされていない場合、未サポートの文字を書き込もうとし、<a href="ja/NS_ERROR_LOSS_OF_SIGNIFICANT_DATA">NS_ERROR_LOSS_OF_SIGNIFICANT_DATA</a> とともに失敗します。
</p>
<h3 id="Gecko_1.8_.E4.BB.A5.E5.89.8D.E3.81.AE.E3.83.90.E3.83.BC.E3.82.B8.E3.83.A7.E3.83.B3" name="Gecko_1.8_.E4.BB.A5.E5.89.8D.E3.81.AE.E3.83.90.E3.83.BC.E3.82.B8.E3.83.A7.E3.83.B3"> Gecko 1.8 以前のバージョン </h3>
<p>Firefox 1.0.x や Mozilla 1.7.x 以前のバージョンでは <code><a href="/ja/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIConverterOutputStream" title="">nsIConverterOutputStream</a></code> をサポートしていません。
</p><p>JavaScript から利用可能な代替策は<b>ヌルの埋め込みを使っている文字エンコーディング</b>(UTF-16 や UTF-32 など)<b>をサポートしていません</b>。手動で <code><a href="/ja/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIScriptableUnicodeConverter" title="">nsIScriptableUnicodeConverter</a></code> を使って書き込みたい文字列をバイト列に変換し、それをストリームに書き込むことになります。
</p><p>以下がその例です。
</p>
<pre class="eval">// まずコンバータの取得と初期化
var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
.createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
converter.charset = /* 使いたい文字エンコーディング:この例では UTF-8 */ "UTF-8";
</pre>
<p>そして変換し、ストリームに書き込みます。
</p>
<pre class="eval">// このコードでは os は nsIOutputStream、
// your_string は書き込みたい文字列と仮定
var chunk = converter.ConvertFromUnicode(your_string);
os.write(chunk, chunk.length);
// 必要に応じ、他の文字列に対しても繰り返し
</pre>
<p>最後に、<code>Finish</code> を呼び出し、データをストリームに書き込む必要があります。
これを必要とする文字エンコーディングはあまりありませんが、これが必要な文字エンコーディングを扱う際に、この作業はきちんとした出力を得るために重要なことなのです。
</p>
<pre class="eval"> var fin = converter.Finish();
if (fin.length > 0)
os.write(fin, fin.length);
os.close();
</pre>
<h2 id=".E3.82.B9.E3.83.88.E3.83.AA.E3.83.BC.E3.83.A0.E3.81.B8.E3.81.AE.E6.96.87.E5.AD.97.E5.88.97.E3.81.AE.E5.A4.89.E6.8F.9B" name=".E3.82.B9.E3.83.88.E3.83.AA.E3.83.BC.E3.83.A0.E3.81.B8.E3.81.AE.E6.96.87.E5.AD.97.E5.88.97.E3.81.AE.E5.A4.89.E6.8F.9B"> ストリームへの文字列の変換 </h2>
<p>文字列をストリームに変換したほうが便利な場合があります。たとえば <code><a href="/ja/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIUploadChannel" title="">nsIUploadChannel</a></code> を使ってアップロードする場合です。
</p><p>この例では Gecko 1.8 (Firefox 1.5、SeaMonkey 1.0) が必要です。
</p><p><code><a href="/ja/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIScriptableUnicodeConverter" title="">nsIScriptableUnicodeConverter</a></code> にはそのためのシンプルなメソッドがあります。
</p>
<pre class="eval">// まずコンバータの取得と初期化
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 として使えるようになった
</pre>
<h2 id=".E9.96.A2.E9.80.A3.E9.A0.85.E7.9B.AE" name=".E9.96.A2.E9.80.A3.E9.A0.85.E7.9B.AE"> 関連項目 </h2>
<p><a href="ja/Reading_textual_data">テキストデータの読み込み</a>
</p>
|