これは InterSystems FAQ サイトの記事です。
InterSystems製品のサーバサイドでファイル入出力を行うと、文字列はシステムで設定されたファイル入出力用文字コードに自動変換され、文字単位でREADします。
ファイルから入力する文字をバイト単位で操作するためには、自動変換を行わない無変換の状態でファイル入力を行い指定バイトずつ読みながら読んだ分だけUnicodeに手動で変換していく必要があります。
変換には$ZCONVERT()関数を使用します。($ZCONVERT()には省略形があり$ZCVT()でも同様の操作が行えます。)
なお、READした指定バイトを変換する際、文字の全バイトが含まれない場合もあるため、途中までの読み取りになった文字列を第4引数に指定する変数に設定できるようになっています。
次回読み取り時に途中だった文字を自動的に先頭に追加し、$ZCONVERT()の処理を実行します。
《メモ》ファイル入出力の文字コードについては、以下管理ポータルの画面で確認できます。
管理ポータル > 構成 > 国際言語設定 > 構成したデフォルト値
入力/出力テーブルの表の「ファイル」
以下の文章がファイルにUTF8で保存されているとします。
無変換でファイル入力を行うには、%Stream.FileBinaryクラスを使用してファイルをオープンします。
5バイトずつ入力する例は以下の通りです。
set fb=##class(%Stream.FileBinary).%New()
write fb.LinkToFile("c:\temp\memoU.txt") //ファイルをリンクできると1が返ります。
set data=fb.Read(5) // 5バイトずつREAD
//UTF8からUnicodeに変換するため第2引数は"I"を指定します
// 第3引数はUTF8(大文字)を指定し、第4引数に変数hadleを指定します。
//write $ZCONVERT(data,"I","UTF8",handle)," - ",handle
//EndOfFileを検出するとAtEndプロパティに1が設定されることを利用してループします。
while (fb.AtEnd=0) { set data=fb.Read(5) write $ZCONVERT(data,"I","UTF8",handle)," - ",handle,! }
kill fb //ファイルをクローズします
While文に含まれるWRITE文の出力結果は以下の通りです。
4/19 - ï
:強 -
風 - ã
でし - ã
たが -
良 - ã
い天 - æ
気で -
し - ã
た
-