はじめに
VBScriptでファイルを扱う場合、通常はFileSystemObjectを利用します。しかしながら、FileSystemObjectはShift_JISあるいはUTF-16形式で保存されたファイルしか扱えません。このため、VBScriptでUTF-8のファイルを扱うにはADODB.Streamオブジェクトを利用します。
CreateTextFileの第3引数をtrueにするとUTF-16でファイルを作る。falseにするとShift_JIS。UTF-8で作ることはできない。UTF-8で作りたいときはFileSystemObjectではなくADODB.Streamを使う。
FileSystemObjectの使い方まとめ - 今日覚えたこと
技術評論社
売り上げランキング: 270,148
ADODB.Streamオブジェクトを利用してファイルの読み込む
ファイル読み込み用のクラスを作成する
Option Explicit Class UTF8FileReader Private name, errNo, errDesc ' コンストラクタ Private Sub Class_Initialize name = "UTF8FileReader" End Sub ' ファイルの中身を戻り値として返す Public Function ReadAll(fileName) On Error Resume Next Dim medthodName : medthodName = name & "." & "ReadAll" With CreateObject("ADODB.Stream") .Charset = "UTF-8" .Open .LoadFromFile(fileName) ReadAll = .ReadText .Close End With If Err.Number <> 0 Then errNo = Err.Number errDesc = Err.Description On Error GoTo 0 Call Err.Raise(errNo, medthodName, errDesc) End If End Function ' ファイルを1行ずつ読み込み、配列に格納して返す Public Function ReadByLine(fileName) On Error Resume Next Dim medthodName : medthodName = name & "." & "ReadByLine" Dim arrRet() ReDim Preserve arrRet(0) With CreateObject("ADODB.Stream") .Charset = "UTF-8" .Open .LoadFromFile(fileName) Do While Not .EOS arrRet(UBound(arrRet)) = .ReadText(-2) ReDim Preserve arrRet(UBound(arrRet) + 1) Loop .Close End With If Err.Number <> 0 Then errNo = Err.Number errDesc = Err.Description On Error GoTo 0 Call Err.Raise(errNo, medthodName, errDesc) End If ReadByLine = arrRet End Function End Class
ファイルをすべて読み込む場合
Set fr = New UTF8FileReader WScript.Echo fr.ReadAll("xxx.txt") If Err.Number <> 0 Then ' エラー処理 End If
1行ずつ読み込み、配列に格納する場合
Set fr = New UTF8FileReader arrText = fr.ReadByLine("xxx.txt") If Err.Number <> 0 Then ' エラー処理 End If
ADODB.Streamオブジェクトを利用してファイルへ書きこむ
ファイル書き込み用のクラスを作成する
Option Explicit Class UTF8FileWriter Private name, errNo, errDesc ' コンストラクタ Private Sub Class_Initialize name = "UTF8FileWriter" End Sub ' 引数で指定された値をファイルに書き込む Public Sub WriteAll(text, fileName) On Error Resume Next Dim medthodName : medthodName = name & "." & "WriteAll" With CreateObject("ADODB.Stream") .Type = 2 .charset = "UTF-8" .Open .writeText text .saveToFile fileName, 2 .Close End With If Err.Number <> 0 Then errNo = Err.Number errDesc = Err.Description On Error GoTo 0 Call Err.Raise(errNo, medthodName, errDesc) End If End Sub ' 配列の中身を1行ずつファイルに書き込む Public Sub WriteByLine(arrText, fileName) On Error Resume Next Dim medthodName : medthodName = name & "." & "WriteByLine" With CreateObject("ADODB.Stream") .Type = 2 .charset = "UTF-8" .Open Dim tmp For Each tmp In arrText .writeText tmp, 1 Next .saveToFile fileName, 2 .Close End With If Err.Number <> 0 Then errNo = Err.Number errDesc = Err.Description On Error GoTo 0 Call Err.Raise(errNo, medthodName, errDesc) End If End Sub End Class
ファイルに一括で書き込む場合
Call fw.WriteAll("ほげ", "yyy.txt") If Err.Number <> 0 Then ' エラー処理 End If
配列の中身を1行ずつ書き込む場合
Call fw.WriteByLine(Array("あ","い","う"), "yyy.txt") If Err.Number <> 0 Then ' エラー処理 End If
UTF-8ファイルを保存しようとした場合にBOMが付加される
- ADODB.StreamオブジェクトのsaveToFileメソッドでUTF-8のファイルを作成した場合、BOMが自動的に付加されるようです。BOMがついていると色々と面倒なことになりそうなので、できれば付加したくないところです。
このため、一度一時ファイルにBOMつきで出力し、その一時ファイルをBOMの部分を読み飛ばして読み込み、再度ファイルに出力するという手段を取ることで回避できるようです。
上記のように「UTF-8」を指定した場合、BOM付きのUTF-8で保存されてしまう。
BOMなしUTF-8は指定できないため、BOMなしにするにはBOMを除去する処理が必要になる。
具体的には以下のような処理を行う。1. 一時ファイルに「UTF-8(BOM付き)」で出力する
2. 一時ファイルを4バイト目から読み込む(BOMが先頭3バイトのため)
3. 読み込んだ4バイト目以降を、出力ファイルに書き出す
4. 一時ファイルを削除する
忘れな〜い録 UTF-8(BOMなし)でファイルを保存する。(VBA)
2009.11.17追記
対処方法が見つかりましたので、以下のエントリにまとめています。