0
0

32BitサーバでSJIS→UTF-8(BOM付)→UTF-8(BOM無)変換のサンプルソース

Posted at

32BitサーバでSJIS→UTF-8(BOM付)→UTF-8(BOM無)変換のサンプルソース

SJIS_to_UTF8.vbs
Option Explicit

On Error Resume Next

' 定数定義
Const adCRLF = -1               '改行コードCRFL
Const adLF = 10                 '改行コードFL
Const adReadLine = -2           'ストリームから次の行を読み取り(LineSeparator指定)
Const adWriteLine = 1           '文字を改行付きで書き込む
Const adTypeBinary = 1          'バイナリモード
Const adTypeText = 2            'テキストモード
Const adSaveCreateOverWrite = 2 '指定したファイルが既に存在する場合、上書き

'変数定義
Dim objInput,objTemp,objOutput
Dim FILEPATH
Dim FILENAME
Dim INPUTFILE

'ファイル操作オブジェクト
Dim objFso

'引数を設定
FILEPATH = Wscript.Arguments(0)
FILENAME = Wscript.Arguments(1)

'変換対象ファイル名を設定
INPUTFILE= FILEPATH & "\" & FILENAME

'ファイル存在チェック
SET objFso = CreateObject("Scripting.FileSystemObject")

If objFso.FileExists(INPUTFILE) Then
else
    '処理を中断
    SET objFso = Nothing
    WScript.Quit 1
End If

'***********************************************
'SJIS→UTF-8(BOM付)
'***********************************************
'入力ファイルオブジェクトを開き、読込設定を行う
Set objInput = CreateObject("ADODB.Stream")
objInput.Open
objInput.Type = adTypeText
objInput.Charset = "Shift_JIS"
objInput.LineSeparator = adCRLF
objInput.LoadFromFile INPUTFILE

'Tempファイルオブジェクトを開き、書込み設定を行う
Set objTemp = CreateObject("ADODB.Stream")
objTemp.Open
objTemp.Type = adTypeText
objTemp.Charset = "UTF-8"
objTemp.LineSeparator = adLF

'入力ファイルの読込
Dim lineStr
Do Until objInput.EOS
    lineStr = objInput.ReadText(adReadLine)
    objTemp.WriteText lineStr, adWriteLine
Loop

'入力ファイルオブジェクトを閉じる
objInput.Close
Set objInput = Nothing

'***********************************************
'UTF-8(BOM付)→UTF-8(BOM無)
'***********************************************
'出力ファイルオブジェクトを開き、書込み設定を行う
Set objOutput = CreateObject("ADODB.Stream")
objOutput.Type = adTypeBinary
objOutput.Open

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

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

'ストリームの位置を先頭3Byte(EF BB BF)の後ろに移動する
objTemp.Position = 3

'BOMなしのバイナリデータを出力ストリームへコピー
objTemp.CopyTo objOutput

'Tempファイルオブジェクトを閉じる
objTemp.Close
Set objTemp = Nothing

'バイナリの内容をファイルに保存(上書き)
objOutput.SaveTofile INPUTFILE, adSaveCreateOverWrite

'出力ファイルオブジェクトを閉じる
objOutput.Close
Set objOutput = Nothing

WScript.Quit 0

【注意点】
32Bitの古いWindowsServerなどでは、ファイルサイズが256MBを超える場合、UTF-8(BOM付)→UTF-8(BOM無)へ変換する際に、3バイト分ポジションをずらしたバイナリを下記のように一気に.Readすると、Dimの変数が、Long型の暗黙変換で、256MBの制限にひっかかってしまう。(0バイトとファイルが出力されてしまう。)

'入力ファイルの読込
Dim objOutput
objOutput = objTemp.Read(-1)

(参考)Size プロパティ (ADO Stream) | Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/access/concepts/miscellaneous/size-property-ado-stream

【解決策】
暗黙変換されたLongに、バイナリを入れるのではなく、"ADODB.Stream"の出力ファイルオブジェクトに3バイト分ポジションをずらしたバイナリObjを.CopyToすることで、Long型の256MB制限にひっかかることなく、BOM無しファイルを出力する事ができる。

'BOMなしのバイナリデータを出力ストリームへコピー
objTemp.CopyTo objOutput
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0