2006/02/20(月) [n年前の日記]
#4 [prog][java] Perlでバイナリを扱う
関連解説をしてるページをメモ。
_Perl の数値変換
_M.Hiroi's Home Page / X68000 Programming / Perl
つまるところ、pack なるものを使うらしい。
_IT覚え書【JAVA】 プログラミング - バイトオーダーの異なるファイルの入出力方法
_Perl の数値変換
_M.Hiroi's Home Page / X68000 Programming / Perl
つまるところ、pack なるものを使うらしい。
◎ Javaってビックエンディアンなのかリトルエンディアンなのか :
どっちだらう。
_データ入出力
_データ入出力
数値データはビッグエンディアン(Big-Endian)のバイトオーダで入出力されるようです。Big-EndianはSPARCやMC68000で採用されているバイトオーダですが、ネットワークのバイトオーダもビッグエンディアンであることから分散環境との相性がよいといえます。ビックエンディアンなのね。
しかし問題なのはIntelの8086系のCPUつまりPentiumはリトルエンディアンで あるということです。つまりWindowsで普通に作成されたデータをJavaのデータ入出力機能では入出力できないのです。その他DataOutputに符号無byteと符号無shortをライトする機能がないことには注意が必要です。データ入出力 より
◎ _Java でリトルエンディアンのバイナリを読む - にっき (2004-04-06) :
昔は自前でバイトオーダーを入れ替える必要があったが、今は java.nio.ByteBuffer があるので、これを使う。なるほど。メモさせてもらおう…。
byte[] buff; // buff にバイナリデータを入れる ByteBuffer bb = ByteBuffer.wrap(buff); // ByteBuffer でラップ bb.order(ByteOrder.LITTLE_ENDIAN); // リトルエンディアンに設定 int intData = bb.getInt(); // 4 バイト読み込む short shortData = bb.getShort(); // 2 バイト読み込む
_IT覚え書【JAVA】 プログラミング - バイトオーダーの異なるファイルの入出力方法
通常、Windows ではリトル・エンディアン (little endian)、Unix系ではビッグ・エンディアン (big endian) が使われている。ただし、Java の入出力クラスでは、ビッグ・エンディアンが優先されている。こちらでも、ByteBuffer を使って、エンディアンを変換する方法が紹介されてる。メモさせてもらおう…。
DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(fileName))); ByteBuffer bb = ByteBuffer.allocate(64); //Little Endian ファイルをそのままのバイトオーダーで読み込み、bb へ代入 bb.putInt(dis.readInt()); bb.putInt(dis.readfloat()); //バイトオーダーを Little Endian に変換して、a と b にそれぞれ代入 bb.order(ByteOrder.LITTLE_ENDIAN); int a = bb.getInt(0); float b = bb.getFloat(4);
◎ Perlでpackを使う場合、エンディアンをどうするかも指定できるっぽい :
_M.Hiroi's Home Page / X68000 Programming / Perl
大きな位から順番に詰めていくのがビッグエンディアンで、小さな位から詰めていくのがリトルエンディアンです。これは使用している MPU によって異なり、X68k の MPU (680x0) はビッグエンディアンとなります。インテル系の MPU は逆にリトルエンディアンです。なるほど…。
エンディアンに左右されたくない場合は、n / N や v / V を使うといいでしょう。
n ネットワークバイト順 (ビッグエンディアン) による short 値
N ネットワークバイト順 (ビッグエンディアン) による long 値
v VAXバイト順 (リトルエンディアン) による short 値
V VAXバイト順 (リトルエンディアン) による long 値
pack( "N", 0x41424344 ) => "ABCD"
pack( "V", 0x41424344 ) => "DCBA"
[ ツッコむ ]
以上です。