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);