こんにちは、初めまして。
さっそくなんですが、バイナリデータの操作を行っていて、ちょっと気になることがあり、質問させて頂きます。
現在あるバイナリデータファイルの読出しには成功し、一応思った通りに書込み、
そのデータは壊れず、読み出せたんですが・・・。

そのバイナリデータファイルは当然のように、アスキー型や文字型、ビッグエンディアンのshortやlongがバイト長ごとに入り混じってます。

アスキー型や文字型は問題なく読み書きできるんですが、
ビッグエンディアンのshortやlongを書き込む時、バイト長を指定してやると、データが壊れてしまいます。

例えば、2バイトのビッグエンディアンのshortを読み出して、そのままリスト値に変換をかけ、なにも加工することなく、再びバイナリ構造体に変換しても、データが壊れてしまいます。

例 失敗) INは読み出すファイル、OUTは書き込むファイル
read (IN,$dataB,2);
$dataA = unpack("n2",$dataB);
$dataB2 = pack("n2",$dataA);
print OUT $dataB2;

現在、packするときに、データ長をしてせず、*とすることでデータの書込みには成功してる(ちゃんと読めるデータとして)んですが、これから先、こういったデータを加工して書き込む場合、データ長を指定せずに書き込むというのは・・・。ちょっと嫌な感じです。

例 成功) INは読み出すファイル、OUTは書き込むファイル
read (IN,$dataB,2);
$dataA = unpack("n2",$dataB);
$dataB2 = pack("n*",$dataA);
print OUT $dataB2;

何が原因なのか、わからず困っています。
なにぶん素人なもので、やってること自体間違っているのかもしれませんが、どなたか御回答頂ければ幸いです。
ここに書いている質問の意図がわからない等、ありましたらその旨お答え頂ければ、私の知る限りお答えしようと思いますので、どうか宜しくお願い致します。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

readの3番目の引数は読みこむバイト数を指定しますが、shortは


2byteですから、2 * 2で4byteを読みこむ必要があります。

それから、unpackを
$data = unpack(...)
の形で受け取るとこれはスカラーコンテクストになりますから、
展開された値の最初の要素だけが$dataに返されます。
@data = unpack(...)
のように配列で受け取れば、リストコンテクストになり、展開された
値すべてが@dataに格納されます。

よって、以下のようにすればお望みの結果が得られるのではないで
しょうか。

read (IN,$dataB,4);
@dataA = unpack("n2",$dataB);
$dataB2 = pack("n2",@dataA);
print OUT $dataB2;

ひょっとしたら、OUTはINと同じファイル、もしくはそれをコピーした
ものなのではありませんか?
だとしたら、「pack("n*", $dataA) にすると成功する」というのは、n2だと
$dataAと空(すなわち0)の二つのshort値が書きこまれる(0で上書きされる
部分がある)のに対し、n*だと$dataAだけをpackした一つのshort値が書き
こまれるので、0で上書きされる個所がない、ということなんだと類推されます。
あるいは実際はもっと複雑なpackを行っていて、他の要素との兼ね合い
があるのかもしれませんが。
    • good
    • 0
この回答へのお礼

お返事遅れてすみませんでした。
全てHead_Syndicateさんのおっしゃる通りで、ばっちりうまくいきました。
ひょっとしたら・・・以下もまさにその通りでした。
本当にありがとうございます。
また、この場にて、質問させて頂く機会があるとは思いますが、そのときはよろしくお願いします。

本当に助かりました。ありがとうございました。

お礼日時:2001/06/15 00:47

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード


おすすめ情報

カテゴリ