北海道苫小牧市出身の初老PGが書くブログ

永遠のプログラマを夢見る、苫小牧市出身のおじさんのちらしの裏

ActivePerlでのUTF-16出力

ActivePerl(Windows上のperl)でUTF-16出力をすると、改行がうまく出力できません*1


なんの変哲もない以下のコードを実行します。UTF16のリトルエンディアンで保存するためのコードです*2

use strict;
use utf8;

open(OUT, '>:encoding(utf-16le)', 'test_open.txt');
print OUT "TEST¥n";
close(OUT);


で、バイナリエディタで中身を見てみます。

0x54 0x00 0x45 0x00 0x53 0x00 0x54 0x00 0x0d 0x0a 0x00


改行コードの部分は、0x0d 0x00 0x0a 0x00となって欲しいのですが、見事に崩れています。"¥n"を"¥x0a"としても結果は同じです。


実は今まで、ActivePerlではソース上の¥nを0x0d 0x0aと言う2バイトとして扱ってるんだと勝手に解釈していたのですが、どうやら違うみたいですね。perl上では0x0aのまま保持し、入出力の直前で、0x0aと0x0d 0x0aの置換をやっているような動きです。binmodeを指定しないとバイナリが崩れるのも、これに起因するってことですか。


ちなみに、以下が解決策です。かなりやな感じですけど。

open(OUT, '>:raw', 'test_enc.txt');
print OUT Encode::encode('utf-16le', "TEST¥n");
close(OUT);

*1:v5.8.8で確認

*2:注: 先頭の0xfeff (BOM)は入れてません。