元気にやっていますか?
私は相変わらず、曖昧な空白とともにふらふらする毎日です。
健体壮美なあなたのことだから大丈夫だとは思いますが、
くれぐれもお体にはお気をつけください。

2009/10/14

[VBScript]UTF-8でファイル入出力(ADODB.Streamオブジェクト)

DOSバッチでちょっとしたファイルの入出力を書こうと思ったら、DOSバッチではUTF-8のテキストデータを扱えないらしい。
ググってみたところ、ActiveXを利用して、JScript、VBScriptならできるということが判明。
以下は、CSVファイルから必要な情報だけを抽出してテキストファイルに出力するコード。
'入力ファイル名(読み出したいファイル)
Dim inputFileName
inputFileName = input.csv
'出力ファイル名(書き出し先ファイル)
Dim outputFileName
outputFileName = output.txt

'入力ストリームの生成・設定(テキスト、UTF-8)
Dim inStream
Set inStream = CreateObject("ADODB.Stream")
inStream.type = 2  '1:バイナリデータ 2:テキストデータ
inStream.charset = "UTF-8"  '入力ファイルの文字コード設定
inStreamopen
inStream.LoadFromFile inputFileName  '入力ファイルを読み込む

'出力ストリームの生成・設定(テキスト、UTF-8)
Dim outStream
Set outStream =CreateObject("ADODB.Stream")
outStream.type = 2
outStream.charset = "UTF-8"  '出力ファイルの文字コード設定
outStream.open

'入力ファイルから一行ずつ読み出して、出力ストリームへ書き出す
Dim records
Do While inStream.EOS = False
  '読み込んだレコードをカンマ区切りで配列に格納
  records = Split(inStream.ReadText(-2), ",")  'ReadTextの第一引数:-1:全部読み込む -2:一行読み込む
  '必要な情報を出力ストリームへ書き出す
  'この例では、CSVファイルの4項目目だけを抽出している
  outStream.WriteText records(3), 1  'WriteTextの第二引数:0:文字列のみ書き込む 1:文字列+改行を書き込む
Loop

'出力ファイル生成
outStream.SaveToFile outputFileName, 2  '1:ファイルがない場合はファイル作成 2:ファイルがある場合は上書き

'ストリームを閉じる
inStream.Close
outStream.Close

'オブジェクトを解放
Set inStream = Nothing
Set outStream = Nothing
ミソは、コイツ。⇒"ADODB.Stream"
本来は、OLE DB(Object Linking and Embedding, Database)のAPIらしく、かなりの高機能。
その一部分をUTF-8のテキストデータに対応したファイル入出力に利用したのでした。
API詳細は、MSDNADO API リファレンスを参照。今回使ったAPIだけだと、Stream オブジェクトに全部載っている。

あと、今回調べていく中で勉強になったのが、VBScriptはメモリ管理を厳重にする必要がないということ。
プログラム終了時に自動的に解放されるらしい。 だから上のコードの「オブジェクトを解放」のくだりは、厳密にはいらないのだ。
ちょっと考えてみれば、お手軽に実行でき、簡単にエラー終了してしまうスクリプト言語が自動的にメモリの解放を行わなかったら、すぐに大変なことになるのは明らかなので、当たり前といえば当たり前なのか。
もちろん、長たらしいコードを書く場合には注意が必要。

その他、今回参考にさせていただいたサイト。
あ、そうそう。このAPIを使用してファイル出力すると、BOMが自動的に付加されてしまうので、BOMを削除したい場合には、ちょっとめんどくさい処理を追加しなければならない。詳しくは、jiroの日記参照。

1 件のコメント:

  1. inStreamopenの間にドットがないですよ

    返信削除