2011年3月7日 星期一

IBM主機中文碼的轉碼

不同系統間的資料傳遞,如果只是單純的英數字資料,就不會碰到麻煩,
但是,如果資料含有中文字,就要特別處理轉碼的問題,
原本處理來自IBM主機資料時,一直 Convert::IBM390這個模組,
也由於之前資料內很幸運的都沒有中文,
所以一直也沒注意到這個無法轉換中文的限制,直到.....今天。

Convert::IBM390只能夠轉換 IBM-1047 <=> ISO8859-1
而 IBM主機上的Traditional Chinese EBCDIC編碼是IBM-937(cp937)
目前Perl在CPAN上面的Encode模組找不到支援cp937
另外唐鳳所寫的模組Encode::IBM可以支援。(但我沒試過)

Unix-like作業系統上,也有一個iconv的指令,可已進行檔案轉碼的作業。
簡單介紹可以參考這裡

所以經由Perl可以間接使用iconv來轉碼,再將結果取回放回變數內,舉例如下。

###############################
# CP937 => Big5 轉碼
# 使用inconv指令
#
sub CP937_BIG5 {

    my $eb = shift;
    return '' unless $eb;

    # 在家目錄/tmp下
    my $big5file = $ENV{HOME} . '/tmp/big5file';
    open Convert, " | iconv -s -f IBM-937 -t big5 > $big5file "  or die;

    print Convert $eb;
    close Convert;

    open B5, '<', $big5file or die;

    my $big5 = <B5>;
    close B5;

    return $big5;

}


如果不想使用上面的方法,也可以改用Text::Iconv,比較簡潔。
###############################
# CP937 => Big5 轉碼
# 使用Text::Iconv來介接inconv指令
#
use Text::Iconv;
sub CP937_BIG5 {

    my $eb = shift;

    if ($eb) {
        return Text::Iconv->new("IBM-937" => "big5")->convert($eb);    
    }
    else {
        return '';
    }
    
}

轉碼是個不得已沒有營養的作業,
但為了現有營運中不同系統間的資料轉換,
它又是個必須存在的基本工具。

Perl提供了良好多樣性的方法來達到我們的目的,是個值得學習而又實用的程式語言。

沒有留言:

張貼留言