X-0021 テキストファイルの入出力

ローカルのテキストファイルの入出力

以下は、テキストファイルの内容を読み込み、文字列として返す関数の例です。

function readFrom(aFile) // nsILocalFile の形でファイルオブジェクトを渡す
{
   var stream = Components.classes['@mozilla.org/network/file-input-stream;1'].createInstance(Components.interfaces.nsIFileInputStream);
   try {
      stream.init(aFile, 1, 0, false); // open as "read only"

      var scriptableStream = Components.classes['@mozilla.org/scriptableinputstream;1'].createInstance(Components.interfaces.nsIScriptableInputStream);
      scriptableStream.init(stream);

      var fileSize = scriptableStream.available();
      var fileContents = scriptableStream.read(fileSize);

      scriptableStream.close();
      stream.close();

      return fileContents;
   }
   catch(e) {
      return null;
   }
}

読み込んだテキストは、ファイルの文字コードそのままで返します。実際に使えるようにするには、文字コードを判別したあとで、 nsIScriptableUnicodeConverter を使って Unicode に変換する必要があります。

今度は、渡した文字列をテキストファイルに保存する関数の例です。これも、渡した文字列の文字コードそのままで出力しますので、必要に応じて、内部コード( Unicode )から Shift_JIS などへ変換してください。

function writeTo(aFile, aContent) // nsILocalFile と、普通の文字列
{
    if (aFile.exists()) aFile.remove(true); // 上書き確認は無し。必要があれば処理を追加。
    aFile.create(aFile.NORMAL_FILE_TYPE, 0666); // アクセス権を8進数で指定。 Win9x などでは無視される。

    var stream = Components.classes['@mozilla.org/network/file-output-stream;1'].createInstance(Components.interfaces.nsIFileOutputStream);
    stream.init(aFile, 2, 0x200, false); // open as "write only"

    stream.write(aContent, aContent.length);

    stream.close();

    return file;
}

というか僕は、読み込んだテキストから文字コードを判別する方法を知りません(ぉぃ)。誰か教えて下さい。

URIで示されたファイルをテキストとして読み込む

前述の処理だと、ローカルのどこかにファイルとして保存されているものしか読み込めません。パッケージの中に含めたファイルを chrome://appname/content/ のようなChrome URLで指定して読み込むには、URIで示されたリソースを読み込んでその中身を返す関数が必要です。

jslib の mozIJSSubScriptLoaderなどはこれを可能にしていますが、mozJSSubScriptLoaderだと中身がJavaScriptでないと動かない&中身をJavaScriptとして評価してしまうので、C++ のソースから「テキストとして読み込む」部分だけを抜き出し、以下にJavaScriptで書き直してみました。

function loadText(aURI) // nsIURI のオブジェクトでヨロ
{
  try {
    const IOService = Components.classes['@mozilla.org/network/io-service;1']
                                .getService(Components.interfaces.nsIIOService);

    var channel = IOService.newChannelFromURI(aURI);
    var stream  = channel.open();

    var scriptableStream = Components.classes['@mozilla.org/scriptableinputstream;1']
                                     .createInstance(Components.interfaces.nsIScriptableInputStream);
    scriptableStream.init(stream);

    var fileContents = scriptableStream.read(scriptableStream.available());

    scriptableStream.close();
    stream.close();

    return fileContents;
  }
  catch(e) {
  }

  return null;
}

これによって、初期設定ファイルをテキストファイルの形でパッケージに入れたりという作り方も可能になります。