DOBON.NET DOBON.NETプログラミング掲示板過去ログ

データをバイナリで開きたい(バイナリエディタで表示するように)

環境/言語:[c#]
分類:[.NET]

またまた教えてほしいことがあり、投稿させて頂きます。

データをバイナリで開いたのですが、バイナリエディタで開いたような表示に
なりません。

いろいろ調べて下記のようにすればいいんじゃないかと思ったのですが・・・

System.IO.Stream stream = System.IO.File.Open(@"c:\T.bmp", System.IO.FileMode.Open);
System.IO.BinaryReader reader = new System.IO.BinaryReader(stream);

while ((reader.ReadByte()) != -1)
{
        ?
}

reader.Close();
stream.Close();


?をどうすれば、バイナリエディタで表示するようにできるのでしょうか?
よろしくお願い致します。
>バイナリエディタで表示するようにできるのでしょうか?
とは具体的にどんな表示でしょうか?

01 12 34 AB CD

みたいな表示でしょうか?
その場合、どこに表示させますか?TextBox?
そして1行どれぐらいのデータを表示させますか?
返信ありがとうございます!

> 01 12 34 AB CD
>
> みたいな表示でしょうか?
> その場合、どこに表示させますか?TextBox?
> そして1行どれぐらいのデータを表示させますか?

たぶんそうだと思うのですが、よくわからないので
下記にバイナリエディタで展開しているgifファイルをアップしました。

42 4D 76 01 00 00 00 00 00 00 36 00 00 00 28 00
00 00 0A 00 00 00 0A…

http://dobon.net/cgi-bin/up/files/014.gif

↑みたいな感じです。

表示はとりあえずtextboxに乗せたいと思ってます。
一行は↑みたいに16文字?で改行したいと思っています。

よろしくお願いします。
>データをバイナリで開いたのですが、バイナリエディタで開いたような表示に
>なりません。
ならなかったというソースを公開してください。
アドバイスできるかも
とりあえず、上の?の中をMessageBoxで開こうとしてみましたが
よく考えると下記ではアルファベットが出そうにないですし・・・

MessageBox.show(reader.ReadDouble().ToString());
.ReadInt32().ToString());

めっちゃ初心者ですいません。。
2006/10/05(Thu) 22:57:53 編集(投稿者)

一バイトずつ取り出して、ToStringでフォーマットしていく感じですね。
まぁ表示だけですが。(編集を考えるとこんなに簡単ではない)
 
C++/CLIで以前何処かで同じような質問に答えたときのコードがありました。
参考にどうぞ。
 
IO::BinaryReader^ br = gcnew IO::BinaryReader( IO::File::OpenRead( op->FileName ) );
// 先にファイルのデータを全部読み込んでおく
array< unsigned char >^ data = br->ReadBytes( ( int )br->BaseStream->Length );
br->Close();
 
String^ buff;
for ( int i = 0; i < data->Length; i++ )
{
    buff += data[ i ].ToString( L"x2" ) + ( ( i % 16 == 15 ) ? L"\r\n" : L" " );
}
this->textBox1->Text = buff;
まず、数値と文字の違いについて理解してください。
#ASCIIコード表を見てみてください。

基本は、数値を目に見える形にする、つまり、
&H1 → "1"(文字コードは&H31)
&HA → "A"(文字コードは&H41)
です。
あとは、バイト値の上位4ビットと下位4ビットに対してそれを処理してあげて表示のための文字列を作ってあげます。
ブルーさん、まどかさん返信ありがとうございます。

array< unsigned char >^ data = br->ReadBytes( ( int )br->BaseStream->Length );br->Close();
この辺をC#にするとどうなるのでしょうか? 変数に入れてるようなのですが
c#しか触ったことがないのでもうひとつわからないです。。


buff += data[ i ].ToString( L"x2" ) + ( ( i % 16 == 15 ) ? L"\r\n" : L" " );
この辺もc#ではどうなりますか? まどかさんが言われてるように出力されている数値を文字に変換しているようなのですが・・・

>まどかさん
ASCIIコード表を検索しました。 出てきた数値をASCIIコード表に基づいて変換すればいいのかな・・・というくらいは少しわかりました
ASCIIコード表も知らなかった&思いつかなかったのんで。
>array< unsigned char >^ data = br->ReadBytes( ( int )br->BaseStream->Length );
一応、MSDNでReadBytesメソッドを見てください。
C#ではどんな値が取得できるのかわかります。
http://msdn2.microsoft.com/ja-JP/library/system.io.binaryreader.readbytes.aspx

>buff += data[ i ].ToString( L"x2" ) + ( ( i % 16 == 15 ) ? L"\r\n" : L" " );
はC#だとほとんどこのままでいけるとおもいます。("のまえのLを消すだけかな?)
ここまでがんばってみたのですがfor文の中どういう意味で
どういう意図でやっているのかわかりません(ガク

参考ページとかあれば教えてください。



System.IO.Stream stream = System.IO.File.Open(@"c:\T.bmp", System.IO.FileMode.Open);
System.IO.BinaryReader reader = new System.IO.BinaryReader(stream);

Array data = reader.ReadBytes((int)reader.BaseStream.Length);
reader.Close();

string buff;
for (int i = 0; i < data.Length; i++)
{
//buff += data(i).Length.ToString("x2");//?
//buff += data(i.ToString("x2"));//?

}
>Array data = reader.ReadBytes((int)reader.BaseStream.Length);
なんでこうなるんだろ、、、

MSDNには
>public virtual byte[] ReadBytes (
> int count
>)
とあるので、戻り値は byte[] だとわかると思うんだけど。

byte[] data = reader.ReadBytes((int)reader.BaseStream.Length);


>for文の中どういう意味でどういう意図でやっているのかわかりません
読み込んだデータを1バイトずつ取り出して、16進表示の文字列を取得して,
buffという文字列の後ろに追記しています。


一度、デバッグして、どんな処理が行われているのか、どんな値が入っているか
やってみると理解しやすいでしょう。
ありがとうございます! 下記でできましたが・・・びっくりするほど
遅いです・・ 教えて頂いた内容に関してはこれから考えるところ
なんですが、なんでこれほどおそいのでしょうか?

byte[] data = reader.ReadBytes((int)reader.BaseStream.Length);
reader.Close();

string buff="";//?
for (int i = 0; i < data.Length; i++)
{
buff += data[ i ].ToString( "x2" ) + ( ( i % 16 == 15 ) ? "\r\n" : " " );
}

this.textBox1.Text = buff;
どこが遅いのかしらべてみましょう。
書き込み不足でした。
for文の中がめちゃめちゃ処理に時間が掛かっているのは
なんとかわかります。 たかだか50kbのbmpデータでも
数秒を要しました。

バイナリエディタは早いのでもっと早い処理方法はないでしょうか?
■No17845に返信(れちりんさんの記事)

とりあえず、自分なら string を StringBuilder にするかな…
ぽぴ王子さんといっしょで
StringをStringBuilderにするのに一票

Stringは処理が遅いといわれてます。
返信頂けたみなさま、ありがとうございます!

下記でなんとかできました。が・・・

System.IO.Stream stream = System.IO.File.Open(@"c:\T.mcx", System.IO.FileMode.Open);
System.IO.BinaryReader reader = new System.IO.BinaryReader(stream);

byte[] data = reader.ReadBytes((int)reader.BaseStream.Length);
reader.Close();


StringBuilder sb = new StringBuilder();

for (int i = 0; i < data.Length; i++)
{
sb.Append(data[i].ToString("x2") + ((i % 16 == 15) ? "\r\n" : " "));
}

this.textBox1.Text = sb.ToString();



肝心の意味がわからないところが多いです…

"x2"の部分は検索してわかったのですが、

((i % 16 == 15) ? "\r\n" : " "

の部分が調べてもよくわかりません?

\r\nは改行コードというのはわかるのですが、他はどういう意味なのでしょうか?
あと、ここだけ教えて頂けないでしょうか?


よろしくお願いします。
>((i % 16 == 15) ? "\r\n" : " "
>の部分が調べてもよくわかりません?
ここは、三項演算子を使って、
>一行は↑みたいに16文字?で改行したいと思っています。
を実現しています。

(iが0〜15のとき)
i は 0 〜 14 のときは(1文字〜15文字のとき)後ろに " " をつけていますが、
15のとき(16文字目のとき)は改行文字をつけています。

同様に % 割り算したときのあまりなので、
iが16〜31のとき、iが32〜47のとき、、、、というように同様な処理をさせています。
2006/10/14(Sat) 20:45:42 編集(投稿者)

返信遅くなり、申し訳ありません。

”三項演算子”を検索してやっとわかりました。
ありがとうございます。

いろいろ教えてくださった皆様、ありがとうございました!
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板