メイン画像

VBScript でのファイル入出力(UTF-8編)

VBScript でのファイル入出力(UTF-8編)


VBScriptでUTF-8のテキストファイルを扱うときはStreamオブジェクトを使う。
書き込みも読み込みもStreamオブジェクトで扱える。

テキストファイルの読み込み手順

  1. ストリームオブジェクトを生成する。

    Dim vStream
    Set vStream = CreateObject("ADODB.Stream")
  2. 文字コードをUTF-8に指定してストリームを開く。

    vStream.Type = 2   'テキストデータを扱う
    vStream.Charset = "UTF-8"
    vStream.Open
  3. テキストファイルをストリームに読み込む。

    vStream.LoadFromFile "C:\path\to\file.txt"
  4. ストリームから文字列を読み取る。

    Dim vText
    vText = vStream.ReadText
  5. ストリームを閉じる。

    vStream.Close
    Set vStream = Nothing

ストリームから文字列を読み取るとき、ReadTextメソッドに何も指定しないと全体を一気に読み取る。

もし行単位で読み取りたい場合、ReadTextメソッドの引数に-2を指定する。

'ストリームを最後まで読み取る(EOSプロパティがTrueを返す)まで繰り返す
Do While vStream.EOS = False
  Dim vText
  vText = vStream.ReadText(-2)    '1行読み取る
Loop

改行文字はLineSeparatorプロパティで設定できる。
(既定値はCR+LF

'CR+LFの場合
vStream.LineSeparator = -1

'LFの場合
vStream.LineSeparator = 10

'CRの場合
vStream.LineSeparator = 13

ReadTextメソッドは、文字数を指定しての読み取りもできる。

指定する文字数は1以上とする。
0 にしたらエラーではなく無限ループとなったので注意したい。

文字数には改行文字もカウントされる。
たとえば、改行文字がCR+LFだった場合、CRで1文字、LFで1文字とカウントされる。

Do While vStream.EOS = False
  Dim vText
  vText = vStream.ReadText(5)    '5文字読み取る
Loop

NOTE: UTF-8、UTF-8(BOM付き)のどちらも読み込める。コードは変わらない。

テキストファイルの書き込み手順

BOMを付けるか付けないかで手順が異なる。

まずは簡単なBOM付きの手順から。
既定でBOMが書き込まれるので、特に何かする必要はない。

  1. ストリームオブジェクトを生成する。

    Dim vStream
    Set vStream = CreateObject("ADODB.Stream")
  2. 文字コードをUTF-8に指定してストリームを開く。

    vStream.Type = 2   'テキストデータを扱う
    vStream.Charset = "UTF-8"
    vStream.Open
  3. ストリームに文字列を書き込む。

    vStream.WriteText "書き込む文字列"
  4. ストリームの内容をファイルに保存する。

    vStream.SaveToFile "C:\path\to\file.txt"
  5. ストリームを閉じる。

    vStream.Close
    Set vStream = Nothing

BOMなしにする

BOMなしのUTF-8ファイルは、BOM付きUTF-8ファイルからBOMを取り除いて作る。

BOMとは、ファイルの先頭にある3バイトの情報を指す。
BOMを取り除くには、BOMより後ろにあるデータをすべて読み取り、読み取ったデータをファイルの先頭から書き込めばよい。

この処理を、ストリームへの文字列書き込み(WriteTextメソッドの処理)とファイル保存(SaveToFileメソッドの処理)の間に追加する。

vStream.WriteText "書き込む文字列"

'ここからがBOMの除去処理
'↓↓↓

'ストリームの位置を先頭に戻す(先頭にないとTypeプロパティを変更できないため)
vStream.Position = 0

'バイナリモードに変える
vStream.Type = 1

'ストリームの位置をBOMの後ろに移動する
vStream.Position = 3

'現在の位置から最後までを読み取る(ここでBOMなしのバイナリデータが取得できる)
Dim vBuf
vBuf = vStream.Read

'読み取ったデータをストリームの先頭から書き込む
vStream.Position = 0
vStream.Write vBuf

'書き込んだデータにはBOMがないので、ストリームの末尾3バイトがゴミとして残っている状態。
'現在の位置をストリームの末尾に設定し、それより後ろ(つまり末尾3バイト)のデータを切り捨てる
vStream.SetEOS

'↑↑↑
'ここまでがBOMの除去処理

vStream.SaveToFile "C:\path\to\file.txt"

関数化しておく

Option Explicit

'StreamTypeEnum
'バイナリデータ
Const adTypeBinary = 1
'テキストデータ
Const adTypeText = 2

'SaveOptionsEnum
'ファイルが存在しない場合のみ新しくファイルを作る。存在する場合はエラーとする
Const adSaveCreateNotExist = 1
'ファイルが存在する場合は上書きする
Const adSaveCreateOverWrite = 2

'StreamReadEnum
'すべて読み取る
Const adReadAll = -1
'行を読み取る
Const adReadLine = -2


'''
''' UTF-8 のテキストファイルを読み込みます。
'''
''' @param {string} piFilePath - 読み込むテキストファイルのパス
''' @return {string} 読み込んだ内容
'''
Function ReadUtf8File (ByVal piFilePath)

  '戻り値初期化
  ReadUtf8File = ""

  With CreateObject("ADODB.Stream")
    'ストリームを開く
    .Type = adTypeText
    .Charset = "UTF-8"
    .Open

    'テキストファイルをストリームに読み込む
    .LoadFromFile piFilePath

    'ストリームからすべての文字列を読み取る
    ReadUtf8File = .ReadText(adReadAll)

    'ストリームを閉じる
    .Close
  End With

End Function


'''
''' UTF-8 のテキストファイルに書き込みます。
'''
''' @param {string} piFilePath - 書き込むテキストファイルのパス
''' @param {string} piTextToWrite - 書き込む内容
''' @param {bool} piWithBom - UTF-8(BOM付き)にするなら True 、UTF-8にするなら False
'''
Sub WriteUtf8File (ByVal piFilePath, ByVal piTextToWrite, ByVal piWithBom)

  With CreateObject("ADODB.Stream")
    'ストリームを開く
    .Type = adTypeText
    .Charset = "UTF-8"
    .Open

    'ストリームに文字列を書き込む
    .WriteText piTextToWrite

    'ストリームの位置を先頭に戻す(先頭にないとTypeプロパティを変更できないため)
    .Position = 0

    'バイナリモードに変える
    .Type = adTypeBinary

    'BOMを取り除く
    If Not piWithBom Then
      'ストリームの位置をBOMの後ろに移動する
      .Position = 3

      '現在の位置から最後までを読み取る(ここでBOMなしのバイナリデータが取得できる)
      Dim vBuf
      vBuf = .Read

      '読み取ったデータをストリームの先頭から書き込む
      .Position = 0
      .Write vBuf

      '書き込んだデータにはBOMがないので、ストリームの末尾3バイトがゴミとして残っている状態。
      '現在の位置をストリームの末尾に設定し、それより後ろ(つまり末尾3バイト)のデータを切り捨てる
      .SetEOS
    End If

    'ファイルに保存する
    '(すでにファイルがあったら実行時エラー 3004 になる)
    .SaveToFile piFilePath, adSaveCreateNotExist

    'ストリームを閉じる
    .Close
  End With

End Sub

アカウントを作成 して、もっと沢山の記事を読みませんか?


この記事が気に入ったら ことりと さんを応援しませんか?
メッセージを添えてチップを送ることができます。


この記事にコメントをしてみませんか?


酒とアクアリウムが最近の楽しみ。

おすすめの記事