Hatena::ブログ(Diary)

jiroの日記 このページをアンテナに追加 RSSフィード

2007-09-22

[]JavaScriptでファイルの書き込みをUTF-8で行う(htaまたは、wsh用)

Windowsデフォルトの機能だけで、ファイルの読み書きを行いたい場合にはhtaやwshを使う必要があります。一般的に知られているのはFileSystemObjectというActiveXObjectを生成して、そのオブジェクトを通してファイルの読み書きを行うのですが、これが自由度が少なく、Shift_JISでしか扱ってくれません。

ADODB.Streamなら他のエンコーディングも扱える

いろいろググって見るとADODB.Streamというのが使えるらしい。じゃあ簡単だと思いやっつけで書いてみたら書き出せた。

と思っていたらBOMに悩まされる

なんかエディタの挙動が違うなぁと思っていたら、なんかUTF-8(BOM)とか書いてあります。何じゃこれってことで調べてみるとUTF-8の場合、ファイルの最初に3バイトにByte Order Markというものがついていて、それが悪さをしているらしい。どうやったら書き出せるか調べてみた。

VBScriptばっかり

そもそもJavaScriptってWindows界隈では人気ないのね。。。で、しかもVBScriptでもまさにこれって事をやってる人がいないので、試行錯誤の上データをUTF-8(BOMなし)で出力する関数を書いてみた。ドキュメントはあんまりないし、ググってもなかなかでてこないので、苦労した。で、結果が下のソースコード。htaのサンプルにもリンクを貼っておくので、自己責任で使用してください

// この関数がファイルを保存する関数
var saveFile = function(filename, text) {
	// ADODB.Streamのモード
	var adTypeBinary = 1;
	var adTypeText = 2;
	// ADODB.Streamを作成
	var pre = new ActiveXObject("ADODB.Stream");
	// 最初はテキストモードでUTF-8で書き込む
	pre.Type = adTypeText;
	pre.Charset = 'UTF-8';
	pre.Open();
	pre.WriteText(text);
	// バイナリモードにするためにPositionを一度0に戻す
	// Readするためにはバイナリタイプでないといけない
	pre.Position = 0;
	pre.Type = adTypeBinary;
	// Positionを3にしてから読み込むことで最初の3バイトをスキップする
	// つまりBOMをスキップします
	pre.Position = 3;
	var bin = pre.Read();
	pre.Close();

	// 読み込んだバイナリデータをバイナリデータとしてファイルに出力する
	// ここは一般的な書き方なので説明を省略
	var stm = new ActiveXObject("ADODB.Stream");
	stm.Type = adTypeBinary;
	stm.Open();
	stm.Write(bin);
	stm.SaveToFile(filename, 2); // force overwrite
	stm.Close();
};

一応説明しておくと、一度Streamに対してUTF-8でデータを書き込みます。その後で、バイナリとして最初の3バイト(BOM分)を読み飛ばしてバイナリを読み出します。読み出したバイナリを新しいStreamにバイナリとして食わせてファイルに保存しました。

なんで、こんなに使いづらいAPIになっているんだろう。。。