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

そのバイナリデータファイルは当然のように、アスキー型や文字型、ビッグエンディアンの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を見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q地熱発電などでいう「バイナリ発電」とは

地熱発電などの文献で「バイナリ発電」という言葉がでてきますが、この意味をお教えください。
そもそも、バイナリ発電という場合の「バイナリ」とは、どういう意味で使用されているのでしょうか。

Aベストアンサー

bi---2と言う意味。バイナリ(二進法)、バイリンガル(二ヶ国語)、バイカラー(二色)、バイセクシャル
 水では気体にならないため、より沸点の低い物質を使って蒸気を得るもの。熱交換器が二つ(バイ)ある。

Qperlスクリプト s/^\s+//;  s/\s+$//;  return wantarray ? @out : $out[0]; について

自作の掲示板を作ろうと思い、perlの勉強をしている者です。人様の作ったスクリプトを解析しています。以下のスクリプトはライブラリに記述されていたものです。


sub tttt {
my @out = @_;
for (@out) {
s/^\s+//;
s/\s+$//;
}
return wantarray ? @out : $out[0];


このスクリプトなんですが、 s/^\s+//; の部分の「+」と s/\s+$//; の部分の「+$」、 また「return wantarray~」 の三つの部分のスクリプトが、どういった働きをしているの分かりません。専門書やウェブ上のリファレンスも色々調べたのですが・・。

分かる方いらっしゃいましたらご教授下さると幸いです。よろしくお願いします。

Aベストアンサー

まず前2つの「+」は,正規表現における,「直前の表現を一回以上繰り返し」をあらわします.
「\s」は空白文字一文字を表す正規表現ですので,「\s+」は,「一文字以上の空白文字」になります.
次に,最初の「^」と2番目の「$」は,その正規表現がどこに現れるかを示す記号です.それぞれ,先頭と最後尾にあることを示します.
したがって,「^\s+」は,「最初に空白が一文字以上ある文字列」に,
「\s+$」は「行末に空白が一文字以上ある文字列」にヒットします.
置換構文sはご存知なんですかね.すなわち,この2文で,行の最初と最後の空白を消しているんです.

次に, wantarray ですが,
http://www2u.biglobe.ne.jp/~MAS/perl/ref/wantarray.html
によると,このサブルーチンttttを呼び出すときに,何を返り値にしているかで真偽が決まる関数です.
呼び出す時に配列を希望していたら @out 全体を,変数を希望していたら $out[0]だけを返します.

Qアプリのバイナリについて バイナリするにはどうすればよいですか?方法を教えて下さい。

アプリのバイナリについて

バイナリするにはどうすればよいですか?方法を教えて下さい。

Aベストアンサー

バイナリするってなんですか?
バイナリファイルを開きたい?
バイナリファイルの場所を知りたい?

よくわかりません

Q$wfurikae = 1 if ( &ccom::getShukujitsu( &com::tD( $wwy,$wwm,$wwd )) ne '' );がよく

$wfurikae = 1 if ( &ccom::getShukujitsu( &com::tD( $wwy,$wwm,$wwd )) ne '' );

というスクリプトがあったのですが、

$wfurikae = 1 の後に;もいれずifがきています。

違和感があります。

どのような意味になるのでしょうか。

宜しくお願い致します。

Aベストアンサー

そのまんまだと思いますよ。
if 以下の条件が真の時 $wfurikae = 1となります。
Perlはいろいろな書き方ができますので、こういう書き方もありです。
英語の文法の並びにする書き方です。

Q[SQLサーバ&勘定奉行]バイナリ順にしてください!?

こんにちわ。

さて・・・。
SQLサーバがインストールされているPCに勘定奉行を入れようとしました。
勘定奉行はSQLを使うのですが・・・。

エラーメッセージで
「SQLサーバがバイナリ順でないためできません」
「バイナリ順に設定してください」
となります。

SQLサーバ7.0のどこをどうすれば「バイナリ順」に設定変更できますか??

Aベストアンサー

バイナリ順に設定しろというのは、やはりとりあえずSQLサーバのBooksOnlineで「並べ替え順」を検索・参照してみて下さい。この事だと思うのですが...。

Qpack("C",0x61).pack("C",0x62)...を省略

$_=pack("C",0x61).pack("C",0x62).pack("C",0x68)...
こういったバイナリ文字列をもっと簡単に$_=0x61.0x62.0x68のように書けませんか?
$_=0x61.0x62.0x68ではうまくいきませんでした。

Aベストアンサー

1行でできます。
$_=pack("C*",0x61,0x62,0x68);

参考URL:http://polaris.isc.nipr.ac.jp/~yama/jare43/tohoho/wwwperl2.htm#pack

Qcgiで表示するhtmlページ内でバイナリ画像を出力したい

cgiで表示するhtmlページ内でバイナリ画像を出力したい

「CGI 画像出力」でググったページで下記のコードがありました。
下記コードは、
Content-typeをimage/gif等にして バイナリを print すれば表示される
という書き方になっていると思いますが、
content-typeがtext/html のページ内でバイナリをprintした場合
バイナリが文字列としてグシャァァァと表示されてしまいます。


-------
$view = 'aaa.jpg';

print "Content-type: image/jpeg\n\n"; #コンテンツタイプを指定する
open IMGG,"$view"; #ファイルハンドル IMGGに画像ファイルを読み込む
binmode (IMGG); #画像なのでバイナリモードに設定する
print <IMGG>; #ファイルハンドルを画面に書き出す
close (IMGG); #ファイルハンドルを閉じる

exit;
-------

content-typeがtext/htmlの状態でバイナリの画像を表示するには
どうすればよいのでしょうか?

cgiを2つ用意して、上記のコードを img src=~~.cgi という形で
呼び出すしかないのでしょうか?

cgiで表示するhtmlページ内でバイナリ画像を出力したい

「CGI 画像出力」でググったページで下記のコードがありました。
下記コードは、
Content-typeをimage/gif等にして バイナリを print すれば表示される
という書き方になっていると思いますが、
content-typeがtext/html のページ内でバイナリをprintした場合
バイナリが文字列としてグシャァァァと表示されてしまいます。


-------
$view = 'aaa.jpg';

print "Content-type: image/jpeg\n\n"; #コンテンツタイプを指定する
open IMGG,"$view"; #ファイル...続きを読む

Aベストアンサー

基本的には、1リクエスト1ファイル返却となりますので、HTMLとJPEGは別々のファイルで返して下さい。

ヘッダー以降に返却されるデータはボディーであり、HTMLの途中からJPEGに変更するってのは反則で通りません。
HTMLの中で単純にバイナリを展開したら無茶苦茶な状態になります。
どうしてもと言うならバイナリをJSコードにして埋めてDOMで再生成とか無茶なやり方は思いつきますが…勧めません。

Q「$" = ',';」という構文の意味は?

Perl スクリプト中に「$" = ',';」という構文が出てきたのですが、これはどういう意味ですか?

Aベストアンサー

"(ダブルクオート)内ではリスト値(@foo)も展開されますが、そのリスト値の区切り文字を定義する特殊変数で、デフォルトはスペースだそうです。

参考URL:http://www.tohoho-web.com/wwwperl1.htm#Tokushu

QPHPのfopenのバイナリモードについて

PHPのfopen時のバイナリモードについて質問です。

PHPのマニュアルにはWINDOWSのようなバイナリとテキストモードの形式の違う
システムでは、画像等のバイナリファイルを扱うときはbを付けてバイナリモードで扱うことが推奨されていますが、
WINDOWS環境でためしたところ、画像ファイルをバイナリではなくテキストモードで開いて中身のデータを読み込んで、別名でfopen("~.jpg","w")で書き込んでも、きちんと表示される画像が作成されました。

テキストモードでバイナリファイルを開いても読み込めってさらに、新規でかきこめるなら
なぜ二つのモードが存在するのでしょうか?

ちなみに、WINDOWSにおけるバイナリとテキストモードの違いって改行文字が
¥nか¥r¥nの違いだけでしょうか?
リナックスではバイナリもテキストも中身の改行文字は¥nとなるのでしょうか?

よろしくお願いします。

Aベストアンサー

Windows以外のOSでは、バイナリモードというのはなく、"wb" "rb" も "w" "r" も同じ動作です。Windowsとのソース互換性のため、"b" をつけてもエラーになりません。

Windowsのバイナリモードはそのままファイルを読み込む/書き込む。テキストモードは、"\r\n" を "\n" に変換しながら読み込み、"\n" を "\r\n" に変換しながら書き込む。

Qopen (FILEHANDLE,"< $filename") or die "エラーメッセージ";について

下記プログラムでperl_read_writes.txtを出力すると、中身が表示されるのですが、a_perl_read_writes.txt等に名前を変更すると、当然エラーが起きます。
が、die "$filenameを開けません。";の部分の
$filenameを開けません。という文章が出力されないのですが、どなたか原因分かりませんか?

==================================================
#!/usr/bin/perl
print "Content-type: text/html;charset=Shift-JIS", "\n\n";

# HTMLの出力
print "<html>\n";
print "<body>\n";
print "ファイルの読み書き<br>\n";

$filename='/usr/local/apache/htdocs/aaa/bbb/perl_read_writes.txt';
# ファイルオープン
open (FILEHANDLE,"< $filename") or die "$filenameを開けません。";
...以下省略
==================================================

よろしくお願いします。

下記プログラムでperl_read_writes.txtを出力すると、中身が表示されるのですが、a_perl_read_writes.txt等に名前を変更すると、当然エラーが起きます。
が、die "$filenameを開けません。";の部分の
$filenameを開けません。という文章が出力されないのですが、どなたか原因分かりませんか?

==================================================
#!/usr/bin/perl
print "Content-type: text/html;charset=Shift-JIS", "\n\n";

# HTMLの出力
print "<html>\n";
print "<body>\n";
print "ファイルの...続きを読む

Aベストアンサー

# > ・・という文章が出力されないのですが、

# ↑どこに出力されないのか? というか、
# エラーメッセージを通常どこで確認しているかが不明ですが、


# エラーメッセージを標準エラーメッセージファイル"STDERR"以外に、
# 画面にも出力するように指定する。
use CGI::Carp qw(fatalsToBrowser);

my $filename = '/usr/local/apache/htdocs/aaa/bbb/a_perl_read_writes.txt';
open (FILEHANDLE,"< $filename") or die "$filenameを開けません。";

# 上記を、手元の
#  WinXP Pro.SP2 + Apache 1.3 + ActivePerl 5.8.4(810) + shift-jis
# で試すと画面(ブラウザ)に以下が出ます。

# (結果)
# /usr/local/apache/htdocs/aaa/bbb/a_perl_read_writes.txtを開けません。at c:\apache\cgi-bin\nu\hoge.pl line nn.

# key word : Perl STDERR, use CGI::Carp

# > ・・という文章が出力されないのですが、

# ↑どこに出力されないのか? というか、
# エラーメッセージを通常どこで確認しているかが不明ですが、


# エラーメッセージを標準エラーメッセージファイル"STDERR"以外に、
# 画面にも出力するように指定する。
use CGI::Carp qw(fatalsToBrowser);

my $filename = '/usr/local/apache/htdocs/aaa/bbb/a_perl_read_writes.txt';
open (FILEHANDLE,"< $filename") or die "$filenameを開けません。";

# 上記を、手元の
#  WinXP Pro.SP2 + Apac...続きを読む


人気Q&Aランキング

おすすめ情報