- - PR -
バイナリファイルの読み取りについて
| 投稿者 | 投稿内容 | ||||
|---|---|---|---|---|---|
|
投稿日時: 2003-08-21 12:00
みなさまお世話になります。
早速でございますが質問させていただきます。 「1.概要」 現在、SWTを用いたデスクトップツールを作成しております。 ツールの機能の一環でデータ読み取り機能を作成する予定で すが読み取り対象のファイルがバイナリ形式であり少々手間 取っております。ファイル内の格納形式(*1)の情報は得 ておりまして、関係者に尋ねたところC等を用いれば読み込 みは出来るのではないかと言われました。 「2.問題点」 バイナリ形式の読み取り方法をどのように実装するのが良い のか。 「3.自分で検討した解決方法」 作成時の選択肢といたしまして次のことを思いつきました。 1.読み取り機能をC言語で作成してJavaモジュール内でネイ ティブ形式で実行する。 2.読み取り機能をJavaで作成する。 3.その他(現在思いついておりません) 可能であれば2.をおこないたいと考えております。 「4.質問」 1.読み取り機能をJavaで作成することは可能なのでしょうか? インターネットなどではJavaの変数情報をバイナリ形式で保 存して読み取るサンプルがあるのですが、CとJavaでは変数の バイト数及びunsigned等の違いがあり、簡単にはできないの かなぁと思っております。 2.(1.が可能な場合) 変数の違いなどは気にする必要は無いのでしょうか? 3.このような読み取りをおこなう場合、どのように作成するの が一般的なのでしょうか? 的外れな質問をしているかもしれませんがよろしくご教授ください。 (*1)格納形式について 以下は格納形式の抜粋です。 struct OSPHEADER { int number; char filter1[11]; double in_mag; int pin; double pin_size; unsigned int time_s; int integ; unsigned int change_bg_f1; unsigned int change_bg_f2; }; | ||||
|
投稿日時: 2003-08-21 12:49
こんにちは。
たとえば・・・ ・読み込んだバイトデータをint型なら、 int data = 上位バイトデータ * 256 + 下位バイトデータ; のように変換する。 ・unsigned int なら、javaには無いので一回り大き目の long を使い、上記と同様に 変換する。 ・charは読み込んだバイト配列をStringに変換する。 とすればいけます。 バイナリファイルの吐き出し元のアプリがどのようにバイナリデータを吐き出して いるかが問題です。 バイナリデータの並びは、cpuやコンパイラによって変わってくるのでよく調べましょう。 また、構造体のメモリ構造をそのままバイナリ出力していれば、ソースコードから見た場 合の1レコードサイズと出力(メモリ確保)されたサイズが違う場合があります。 | ||||
|
投稿日時: 2003-08-21 13:35
jdk1.4であれば、java.nio.ByteBufferに1レコード分を読み込んで、
getInt(オフセット)などとするのが楽でしょうね。 unsigned intなデータは long time_s = buffer.getInt(オフセット) & ((1L << 32) - 1); でOKでしょう。 | ||||
|
投稿日時: 2003-08-21 14:14
素直にJavaでやればOKだと思いますよ。
maruさんの言うように、 > バイナリデータの並びは、cpuやコンパイラによって変わってくる ですので、構造体の定義ではなく、ファイルのフォーマットとして 提供してもらったほうが確実です。 # intは何バイト? doubleは何バイト? などなど java.io.DataInputStream#read()あたりでバイト配列の読み込みが できるでしょうから、intだのunsigned intだのを注意深く変換すれば 良いですね。 | ||||
|
投稿日時: 2003-08-25 13:11
みなさまおせわになります。
以前皆様からご指導頂きまして、独自で試行錯誤してみたのですが 不明な点が発生したのでまたまたお世話になりたいと思います。 「概要」 Cで単純な構造体をバイナリ形式で保存しました。 --構造体begin-- struct sample{ short code; }; --構造体に格納したデータです-- code->1 --16進数で表示した結果です-- code->0x0100 「質問」 short型は16Bit(2Byte)だと思うのですが。 16進数表示をおこなったら0x0100と表示されました。 私が思うには後ろの0x00はNULLを表していると思うのですが、 前の0x01は1バイトではないのでしょうか? | ||||
|
投稿日時: 2003-08-25 13:55
こんにちは。
「16進数で表示した結果」というのが、なにで表示したものといっているのかが不明です。 Cの開発環境上で変数の内容を16進表示してみたのか、バイナリ形式で保存したファイル をバイナリエディタなんかで表示してみたのか。 後者であれば、リトル・インディアンのためではないですか? インテル系CPUでは、下位バイトが先(下位アドレス)にきますので、そういうならびに なりますが・・・? データの並びがCPUやコンパイラによって変わるといっていたのは、そういう意味も含めて いっていました。 | ||||
|
投稿日時: 2003-08-25 14:02
C言語で書かれたのならJava会議室で質問するのは不適当ではないかなどという突っ込みは置いておきまして ^^;
バイナリ形式で保存したとのことですが、具体的にどのようにコーディングされたのでしょうか?プログラムを見てみないことには何とも判断できないと思いますが・・・ | ||||
|
投稿日時: 2003-08-25 14:19
みなさまありがとうございます。! >「16進数で表示した結果」というのが、なにで表示したものといっているのかが不明です。 >Cの開発環境上で変数の内容を16進表示してみたのか、バイナリ形式で保存したファイル >をバイナリエディタなんかで表示してみたのか。 >後者であれば、リトル・インディアンのためではないですか? 後者で確認しました。 >インテル系CPUでは、下位バイトが先(下位アドレス)にきますので、そういうならびに >なりますが・・・? 私ももしかして?と思って12345を16進数で表示してみたら0x3930となりました。 この場合は下位と上位のバイトを単純に入れ替えればよろしいのでしょうか? >C言語で書かれたのならJava会議室で質問するのは不適当ではないかなどという突っ込み >は置いておきまして Cの構造体(バイナリ形式で保存)をJavaで読み取りたいと考えており質問させていただき ました。 --以下はsorceの抜粋です-- void sample::test(void) { sample dat; //構造体です dat.code = 12345; FILE *fp; fp = fopen("c:\\data","wb"); fwrite(&dat,sizeof(dat),1,fp); fclose(fp); } | ||||
