これは InterSystems FAQ サイトの記事です。
InterSystems 製品では、ファイルオープン時に文字コードを指定すれば指定の文字コードで正しくファイルの中身を処理できます。
文字コードを指定しない場合、InterSystems 製品をインストールした OS に合わせて設定されたファイル I/O 用文字コードを利用してファイルをオープンします(Linux 系は UTF8、Windows は SJIS)。
また、文字列については文字コードが判明していれば $ZCONVERT() 関数を使用して指定文字コードで文字列を処理することができます。
例)$ZCONVERT(文字列,"I","IRIS内文字コード")
文字コードが不明な場合、残念ながら InterSystems 製品だけでそのコードを判別することができないため、例えば Embedded Python で Python の chardet パッケージを使用して文字コード判別し、IRIS 内文字コードを取得しファイルオープン、文字列の文字コード変換をすることができます。
chardetパッケージについては、外部サイトですが参考となります。ぜひご参照ください。
参考ページ:[解決!Python]テキストファイルのエンコーディングを調べて、その内容を読み込むには(chardetパッケージ)
以下、具体的な処理内容です。文字コードが不明なファイルに対する処理例として記載しています(文字列に対する処理例は末尾にあります)。
IRIS のクラス定義に以下のように language=python を設定したクラスメソッドを用意します。
/// ファイルのエンコードを確認して返す
/// 第1引数:ファイル名(フルパス)
/// 戻り値:エンコード
/// 事前準備:Pythonのchardetパッケージをインストールしておく必要があります
/// 参考URL:https://atmarkit.itmedia.co.jp/ait/articles/2105/11/news015.html
ClassMethod GetEncode(filename As %String) As %String [ Language = python ]
{
import iris
from chardet import detect
with open(filename, 'rb') as f:
b = f.read()
enc = detect(b)
return enc["encoding"]
}
ターミナルで単体テストを行った結果は以下の通りです。
例:ECU-JPで保存されているファイルを確認した場合
.png)
この後、IRIS 内ユーティリティメソッドを利用して IRIS 用文字コードを入手しファイルオープン時の文字コードに指定します。
set TranslateTable=##class(%Net.Charset).GetTranslateTable(ここにPythonで確認したエンコード)
コード詳細は以下の通りです。
ClassMethod test(filename As %String)
{
if $Get(filename)="" {
write "第1引数にファイル名をフルパスで指定してください",!
return
}
set encode=..GetEncode(filename)
if $get(encode)="" {
write filename," のエンコードが入手できませんでした",!
return
}
set TranslateTable=##class(%Net.Charset).GetTranslateTable(encode)
write "IRISの文字コードは:",TranslateTable,!
write "ファイルの中身は以下==",!
set fs=##class(%Stream.FileCharacter).%New()
set fs.TranslateTable=TranslateTable
do fs.LinkToFile(filename)
while fs.AtEnd=0 {
write fs.ReadLine(),!
}
kill fs
}
実行例は以下の通りです。
USER>do ##class(FAQ.Utils).test("/data/sample1.txt")
IRISの文字コードは:EUC
ファイルの中身は以下==
あいうえお
かきくけこ
さしすせそ
USER>
ファイルではなく文字列に対して操作する場合は、以下の手順で実行します。
1、Python の chardetパッケージを利用してエンコードを入手
set encode=##class(FAQ.Utils).GetEncode("/data/sample1.txt")
2、IRIS 用文字コードを入手
USER>set TranslateTable=##class(%Net.Charset).GetTranslateTable(encode)
USER>write TranslateTable
EUC
USER>
3、$ZCONVERT()関数を使用してコードを変換
USER>write $ZCONVERT(reco,"I",TranslateTable)
あいうえお
USER>