トップ回答者
バイナリデータの指定したアドレスをTextboxに書き出す方法

質問
-
回答
-
これだと、NullReferenceExceptionになりますよね。
確かに、ReadBytesメソッドのサンプルではMemoryStreamクラスを使っているため、ファイルと結びつかないかもしれませんが、BinaryReaderクラスのページを漁っていくと、ファイルを使ったサンプルも出てきますよ。
http://msdn.microsoft.com/ja-jp/library/system.io.binaryreader.aspx
こういったページを見つけられなくとも、検索エンジンで「BinaryReader VB.NET サンプル」とか検索してみると良いかもしれませんね。
あとは、ReadBytesメソッドはByte型の配列を返すので、それをGetStringに突っ込んで、得られたStringをTextBoxに表示するとかですかね。
ただ、今のままだと、ShiftJISで解釈できないバイトが含まれていると、例外が出るか、そのバイトがなかったこととして扱われるかもしれません。
その対策も考えてみて下さい。(EncoderReplacementFallbackやDecoderReplacementFallbackとか)
参考になった返信には「回答としてマーク」のボタンを利用して、回答に設定しましょう(未解決の場合を除く)。- 回答としてマーク sk7474 2009年3月3日 9:17
-
エラーの原因は、Dim testArray As Byte() = {0, 0, 0, 0} では 4 バイト
しか確保されてないからでしょう。(6 バイト必要)> 上記コードでもしバイナリ6バイトを読み取れたとして、Encoding.GetString
> へはどのように渡すのでしょうか?GetString メソッドの引数に testArray を渡せば、その戻り値が文字列になり
ます。Encoding は Azulean さんのレスにあったように、Shift_JIS として解釈
できないバイトの取り扱いに要注意です。さらに、解釈できても表示できないバイト(例えば、0x00 とか改行など)をピ
リオド '.' で表示したい場合は GetString する前に処置が必要です。ところで、前の質問に、
> 画像通り、水色で囲った部分をTextboxに書き出したいです。
とありましたが、「水色で囲った部分」は 16 バイトです。6 バイトでいいん
ですか?- 回答としてマーク sk7474 2009年3月3日 9:16
-
ニホンゴムズカシイ…。
質問に単純に答えるなら、TextBox.Text = "0" ですが、やりたいことは違いますよね。
Tanukichiさんの言う「バイナリ」とは何のことでしょうか?
また「アドレス"0"」とは何のでしょうか? 一般に言われるアドレス"0"、つまりIntPtr.Zeroにはほぼ確実に期待するものは入っていません。
更に「バイナリ」をどのように文字列化することを考えていますか?
つまずいているのではなく、Tanikichiさんが「ご自身のやりたいこと・わからないこと」をわからないだけだと思います。
実際、質問文を読み返してみてください。フォルダやファイルといったキーワードに触れられていますが、肝心の質問とは無関係に受け取れます。
- 回答としてマーク sk7474 2009年3月3日 9:18
-
こんばんは。
最後の「バイナリを読み取りTextboxに表示」ができていないということですが、
その前段には「Listbox内ファイルを選択」とあります。
これは何かファイルを読み込んで、その内容の指定位置からデータを読み取り表示したい、
ということでしょうか?
もしそういうことでしたら、このファイル読込は上手くいっていますか?
FileStreamクラスを使うと、指定位置から指定サイズでバイトデータを読み込むことが出来ます。
ただ、質問の意図を読み違えたら申し訳ありません。
あと、Tanukichi の発言:というのは、「アドレスが00000000の位置から」ということなんでしょうか。"バイナリエディタのアドレスが00000000の文字列(50 53 5A...などではなくPSZ...)をTextboxに表示したい"
- 回答としてマーク sk7474 2009年3月3日 9:18
-
Tanukichiさん の発言:例えば以下の記事はいかがでしょうか?
FileStreamのサンプルがどこのサイトも完全に読み取る方法しかなく、自分には理解できないコードだったため使えませんでした。
解説しているサイトもしくは簡素的でもいいのでサンプルをくださいませんか?
バイナリ・ファイルを読み書きするには?[C#、VB]
http://www.atmarkit.co.jp/fdotnet/dotnettips/669bincopy/bincopy.html
★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/- 回答としてマーク sk7474 2009年3月3日 9:17
-
「バイナリデータの指定したアドレス」とかいう表現なので話がややこし
くなっているだけのように思えます。要するに、メモ帳などのテキストエディタで作ったテキストファイルの最
初の一行を読んで TextBox に表示したいということだと思うのですが。そうであれば、エンコーディングが分かれば以下のようにして表示できる
はずです。Using sr As New StreamReader(path, encoding) TextBox1.Text = sr.ReadLine() End Using
エンコーディングを取得する法は、以下のサイトが参考になると思います。
文字コードを判別する
http://dobon.net/vb/dotnet/string/detectcode.html
なお、エンコーディングが不明でも、メモ帳で UTF-8, Unicode, Unicode
Big Endian で作ったものであれば、以下のようにして表示できます。Using sr As New StreamReader(path) TextBox1.Text = sr.ReadLine() End Using
ANSI はダメです。日本語が文字化けします。- 回答としてマーク sk7474 2009年3月3日 9:17
-
Tanukichi の発言:
なんか説明が悪かったようです...
すらっとまとめると
"バイナリエディタのアドレスが00000000の文字列(50 53 5A...などではなくPSZ...)をTextboxに表示したい"
ということです。
ちょっと説明がほんとに下手なのですがよろしくお願いします。
「50 53 5A などではなく、 PSZ」ということですが、まず、文字コードは何でしょう?最初の投稿には、「バイナリデータ」と書かれています。ここにある例、50 53 5A は、日本でよく使われる ANSI または Shift_JIS または EUC_JP または JIS では、PSZ となります。では、20 0A 08 07 というデータだったら、どう表示しましょうか?
「読み取りたいバイナリのアドレスは、"0" の一行のみです」と言うことですがバイナリ データに「行」という概念はありません。何バイト表示すればよろしいでしょうか?
「解説しているサイトもしくは簡素的でもいいのでサンプルをくださいませんか?」ということですが、何がしたいのかわからないので、示すことができません。何らかの文字コードで解釈したときに、可視文字のみで構成されているファイル(いわゆるテキスト ファイル)から表示したいのか(SurferOnWwwさんのコードをどうぞ)、不可視文字も含めたファイル(バイナリ ファイル)から可視文字のみ抜き出したいのか、解りません。
テキスト ファイルの1行目をプレビューしたい、というのが真意のような気がするけど...
Jitta@わんくま同盟- 回答としてマーク sk7474 2009年3月3日 9:17
すべての返信
-
ニホンゴムズカシイ…。
質問に単純に答えるなら、TextBox.Text = "0" ですが、やりたいことは違いますよね。
Tanukichiさんの言う「バイナリ」とは何のことでしょうか?
また「アドレス"0"」とは何のでしょうか? 一般に言われるアドレス"0"、つまりIntPtr.Zeroにはほぼ確実に期待するものは入っていません。
更に「バイナリ」をどのように文字列化することを考えていますか?
つまずいているのではなく、Tanikichiさんが「ご自身のやりたいこと・わからないこと」をわからないだけだと思います。
実際、質問文を読み返してみてください。フォルダやファイルといったキーワードに触れられていますが、肝心の質問とは無関係に受け取れます。
- 回答としてマーク sk7474 2009年3月3日 9:18
-
こんばんは。
最後の「バイナリを読み取りTextboxに表示」ができていないということですが、
その前段には「Listbox内ファイルを選択」とあります。
これは何かファイルを読み込んで、その内容の指定位置からデータを読み取り表示したい、
ということでしょうか?
もしそういうことでしたら、このファイル読込は上手くいっていますか?
FileStreamクラスを使うと、指定位置から指定サイズでバイトデータを読み込むことが出来ます。
ただ、質問の意図を読み違えたら申し訳ありません。
あと、Tanukichi の発言:というのは、「アドレスが00000000の位置から」ということなんでしょうか。"バイナリエディタのアドレスが00000000の文字列(50 53 5A...などではなくPSZ...)をTextboxに表示したい"
- 回答としてマーク sk7474 2009年3月3日 9:18
-
Tanukichi さん の発言:
ListBoxの内容を選択するとファイルパス(C:\a\a.txtなど)がtextbox1に挿入されているのでそこからファイルを指定してファイルを開こうと思っています。
アドレスが00000000の文字列というのは要するに最初の一行目です。バイナリエディタのアドレスですが。
FileStreamのサンプルがどこのサイトも完全に読み取る方法しかなく、自分には理解できないコードだったため使えませんでした。
解説しているサイトもしくは簡素的でもいいのでサンプルをくださいませんか?
よろしくお願いします。
先頭の位置から16バイト程度読み取れば良いのでは?
大抵の場合、FileStreamで開いた状態では、先頭の位置にありますので、そこからByte配列で16個分、読めば良いのかもしれません。
(明示的に先頭の位置に移動するというSeekをしておくのも手)
そのByte配列をどうやって文字列にするかは、文字コード次第です。
あなたが表示したいのはUTF-8なのか、ShiftJISなのか、UTF-16なのか、EUC-JPなのか、指定がありませんので、それについては何とも言えません。
Encodingクラスとか使えばなんとかなるとは思いますが。
ただ、文字として16個分読み取りたいのであれば、先の「Byte配列で16個決め打ちで読み込む」方針はまずいかもしれませんね。
あとは本筋と離れた姿勢の話となりますが、今後のためにも記しておきます。
「見つけた/提示されたサンプルが自分には理解できないので使えない」と言われると、何も提示できなくなります。
「自分で理解できる」というのは、第三者から見ると量りようのない基準であり、それに沿った説明をしているページであると判断することや、回答者自らが説明を行うことは不可能です。
「理解できないから使えない」ではなく、「理解するために教えて欲しい」ならまだ相談に乗ってもらえるかもしれません。
参考になった返信には「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に指定できます)。 -
Tanukichiさん の発言:例えば以下の記事はいかがでしょうか?
FileStreamのサンプルがどこのサイトも完全に読み取る方法しかなく、自分には理解できないコードだったため使えませんでした。
解説しているサイトもしくは簡素的でもいいのでサンプルをくださいませんか?
バイナリ・ファイルを読み書きするには?[C#、VB]
http://www.atmarkit.co.jp/fdotnet/dotnettips/669bincopy/bincopy.html
★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/- 回答としてマーク sk7474 2009年3月3日 9:17
-
「バイナリデータの指定したアドレス」とかいう表現なので話がややこし
くなっているだけのように思えます。要するに、メモ帳などのテキストエディタで作ったテキストファイルの最
初の一行を読んで TextBox に表示したいということだと思うのですが。そうであれば、エンコーディングが分かれば以下のようにして表示できる
はずです。Using sr As New StreamReader(path, encoding) TextBox1.Text = sr.ReadLine() End Using
エンコーディングを取得する法は、以下のサイトが参考になると思います。
文字コードを判別する
http://dobon.net/vb/dotnet/string/detectcode.html
なお、エンコーディングが不明でも、メモ帳で UTF-8, Unicode, Unicode
Big Endian で作ったものであれば、以下のようにして表示できます。Using sr As New StreamReader(path) TextBox1.Text = sr.ReadLine() End Using
ANSI はダメです。日本語が文字化けします。- 回答としてマーク sk7474 2009年3月3日 9:17
-
Tanukichi の発言:
なんか説明が悪かったようです...
すらっとまとめると
"バイナリエディタのアドレスが00000000の文字列(50 53 5A...などではなくPSZ...)をTextboxに表示したい"
ということです。
ちょっと説明がほんとに下手なのですがよろしくお願いします。
「50 53 5A などではなく、 PSZ」ということですが、まず、文字コードは何でしょう?最初の投稿には、「バイナリデータ」と書かれています。ここにある例、50 53 5A は、日本でよく使われる ANSI または Shift_JIS または EUC_JP または JIS では、PSZ となります。では、20 0A 08 07 というデータだったら、どう表示しましょうか?
「読み取りたいバイナリのアドレスは、"0" の一行のみです」と言うことですがバイナリ データに「行」という概念はありません。何バイト表示すればよろしいでしょうか?
「解説しているサイトもしくは簡素的でもいいのでサンプルをくださいませんか?」ということですが、何がしたいのかわからないので、示すことができません。何らかの文字コードで解釈したときに、可視文字のみで構成されているファイル(いわゆるテキスト ファイル)から表示したいのか(SurferOnWwwさんのコードをどうぞ)、不可視文字も含めたファイル(バイナリ ファイル)から可視文字のみ抜き出したいのか、解りません。
テキスト ファイルの1行目をプレビューしたい、というのが真意のような気がするけど...
Jitta@わんくま同盟- 回答としてマーク sk7474 2009年3月3日 9:17
-
ANSI 、 Shift_JIS 、 EUC_JP でPSZ...の読み取りたい文章を読み取れました。
読み取るのは特定の種類のファイルなので上記3つのどれかで読み取れればOKです。
わかる方、ご教授をお願いします。
>「見つけた/提示されたサンプルが自分には理解できないので使えない」と言われると、何も提示できなくなります。
>「自分で理解できる」というのは、第三者から見ると量りようのない基準であり、それに沿った説明をしているページであると判断することや、回答者自らが説明を行うことは不可能です。
>「理解できないから使えない」ではなく、「理解するために教えて欲しい」ならまだ相談に乗ってもらえるかもしれません。
そうですね...自分の考え方が甘かったようです。反省します。 -
このようなことをしたいです。
http://imepita.jp/20090211/565800
(バイナリエディタの画像)
画像通り、水色で囲った部分をTextboxに書き出したいです。
アドバイス、よろしくお願いします。 -
Tanukichi さん の発言:この「アドバイス」って何を求めているのでしょうか?
アドバイス、よろしくお願いします。
使うクラスやメソッドだけを紹介すれば十分なのでしょうか?
BinaryReader.ReadBytes(ファイルから読み取り)、Encoding.GetEncoding(ASCIIでかつ認識できないバイトを"."に置き換えるFallbackをセットしてEncodingインスタンスを取得)、Encoding.GetString(渡したbyte配列を文字列に変換)あたりを組み合わせればできるんだとは思います。
参考になった返信には「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に指定できます)。 -
回答ありがとうございます。
http://msdn.microsoft.com/ja-jp/library/system.io.binaryreader.readbytes.aspx
を参考にしたのですが
”returnValue = instance.ReadBytes(count)”のどの部分で開くファイルを指定するか、取得した文字列(バイト?)をどこに出力するか
がわからないのですが、今後のためにも教えていただけないでしょうか?Dim instance As System.IO.BinaryReader Dim count As Integer = 6 Dim returnValue As Byte() Dim Enc As System.Text.Encoding = System.Text.Encoding.GetEncoding("Shift_JIS") Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged TextBox2.Text = (ListBox1.SelectedItem)
'この部分わからないreturnValue = instance.ReadBytes(count) End Sub -
これだと、NullReferenceExceptionになりますよね。
確かに、ReadBytesメソッドのサンプルではMemoryStreamクラスを使っているため、ファイルと結びつかないかもしれませんが、BinaryReaderクラスのページを漁っていくと、ファイルを使ったサンプルも出てきますよ。
http://msdn.microsoft.com/ja-jp/library/system.io.binaryreader.aspx
こういったページを見つけられなくとも、検索エンジンで「BinaryReader VB.NET サンプル」とか検索してみると良いかもしれませんね。
あとは、ReadBytesメソッドはByte型の配列を返すので、それをGetStringに突っ込んで、得られたStringをTextBoxに表示するとかですかね。
ただ、今のままだと、ShiftJISで解釈できないバイトが含まれていると、例外が出るか、そのバイトがなかったこととして扱われるかもしれません。
その対策も考えてみて下さい。(EncoderReplacementFallbackやDecoderReplacementFallbackとか)
参考になった返信には「回答としてマーク」のボタンを利用して、回答に設定しましょう(未解決の場合を除く)。- 回答としてマーク sk7474 2009年3月3日 9:17
-
回答ありがとうございます
'Const fileName As String TextBox2.Text Dim fileName As String = TextBox2.Text On Error GoTo e Dim binReader As New IO.BinaryReader( _ File.Open(fileName, FileMode.Open)) Dim testArray As Byte() = {0, 0, 0, 0} Dim count As Integer = binReader.Read(testArray, 0, 6) e: fi.Text = Err.Description
配列のオフセットおよび長さが範囲を超えているか、カウンタがソース コレクションのインデックスから最後までの要素の数より大きい値です。
が表示されました。
このコードで自分がやりたいことは「Textbox2に表示されているパスを読み取り、そのファイルのバイナリ6バイトを取得する」をやっているつもりです。
どこが間違っているか、どこを訂正したほうが教えていただけますでしょうか?
あと、上記コードでもしバイナリ6バイトを読み取れたとして、Encoding.GetStringへはどのように渡すのでしょうか?
よろしくお願いします。 -
エラーの原因は、Dim testArray As Byte() = {0, 0, 0, 0} では 4 バイト
しか確保されてないからでしょう。(6 バイト必要)> 上記コードでもしバイナリ6バイトを読み取れたとして、Encoding.GetString
> へはどのように渡すのでしょうか?GetString メソッドの引数に testArray を渡せば、その戻り値が文字列になり
ます。Encoding は Azulean さんのレスにあったように、Shift_JIS として解釈
できないバイトの取り扱いに要注意です。さらに、解釈できても表示できないバイト(例えば、0x00 とか改行など)をピ
リオド '.' で表示したい場合は GetString する前に処置が必要です。ところで、前の質問に、
> 画像通り、水色で囲った部分をTextboxに書き出したいです。
とありましたが、「水色で囲った部分」は 16 バイトです。6 バイトでいいん
ですか?- 回答としてマーク sk7474 2009年3月3日 9:16
-
ありがとうございます!
Textboxに書き出すことができました。
しかし、"00"の部分があると"00"以降の文字列が書き出してくれません...
(http://imepita.jp/20090215/447830)
できれば、"00"の部分を半角スペースにしようと思い、Dim sp As New EncoderReplacementFallback(" ") Dim df As New DecoderReplacementFallback(" ") Dim Enc As Encoding = Encoding.GetEncoding("Shift_JIS", sp, df)
testArray = Replace(testArray, "00", " ")
どのようにすれば"00"以降を書き出せるのでしょうか?回答、よろしくお願いします
>それと、PSZ って、なんか、引っかかるのですが、ゲームか何かのセーブデータを逆アセンブルしようとしているのではないですよね?
違います。逆アセンブルなんて初心者の自分が知識など持っているはずがなく、興味もありません。 -
Dim count As Integer = binReader.Read(testArray, 0, 16) で testArray に
読み込んだ後、その中身がどうなっているかデバッガで見て調べてください。
(デバッガで表示されるのは 10 進数で、バイナリエディタで表示されるのは
16 進数なので注意)読めていれば表示できると思います。
以下のコードで試してみたらどうなりますか? これで OK で、ファイルから
読むと NG なら、うまくファイルを読み込めてないか、ファイルの中身が違う
のだと思います。Dim testArray As Byte() = {&H50, &H53, &H5A, &H5A, &H0, &H0, _ &H0, &H0, &H4E, &H4E, &H4E, &H4E, _ &H4E, &H4E, &H0, &H0} Dim sp As New EncoderReplacementFallback(" ") Dim df As New DecoderReplacementFallback(" ") Dim enc As EncodingEncoding = Encoding.GetEncoding("Shift_JIS", sp, df) TextBox1.Text = enc.GetString(testArray) -
ReplacementFallbackは変換できない文字を置き換えるという目的なので、今回のnull文字(他、制御文字を含む)については正常に変換できてしまうんですね。
null文字は文字列の終端を意味する意図もあるので、それ以降の文字が表示されないといった現象として出てきています。
これの対策をしようとすると、表示できる文字・表示できない文字を区別できないといけないんですが、どうしたもんかな。Encoding.ASCIIで変換した後に、Char.IsControlとか、Char.IsWhiteSpaceで制御文字と空白文字の判別はできそうだけども、ちょっと手間がかかりそうな感じがしますね。
他に良い方法あるかなぁ。
参考になった返信には「回答としてマーク」のボタンを利用して、回答に設定しましょう(未解決の場合を除く)。 -
> null文字は文字列の終端を意味する意図もあるので、それ以降の文字が表示さ
> れないといった現象として出てきています。コンソールアプリで試して PSZZ NNNNNN と表示されたので、どれも同じだろ
うと思っていたんですが・・・実際試してみるとそうではなくて、Windows アプリの TextBox では PSZZ でした。
ちなみに、Web アプリの TextBox では PSZZNNNNNN(ソースを表示すると何故か
value="PSZZ NNNNNN ")と、いずれも違う結果になりました。どうもゼロは終端文字を意味するというわけではなくて、表示結果がどうなるか
は未定義ということではないのでしょうか?というわけで、以下のような感じで表示できないバイトを空白に置き換えないと
ダメなようです。(あくまで「感じ」です。PSZZ NNNNNN は表示できるのは
確認しましたが、それ以外のバイト列で十分に検証してないのでバグがあっ
たらすみません)Dim testArray As Byte() = {&H50, &H53, &H5A, &H5A, &H0, &H0, _ &H0, &H0, &H4E, &H4E, &H4E, &H4E, _ &H4E, &H4E, &H0, &H0} For i As Integer = 0 To testArray.Length - 1 ' 日本語の第2バイトか ASCII かは直前のバイトが 0x80 以上かどうかで判断。 If testArray(i) > &H7F Then i += 1 Continue For End If If testArray(i) < &H20 OrElse testArray(i) > &H7E Then testArray(i) = &H20 End If Next Dim sp As New EncoderReplacementFallback(" ") Dim df As New DecoderReplacementFallback(" ") Dim enc As Encoding = Encoding.GetEncoding("Shift_JIS", sp, df) TextBox1.Text = enc.GetString(testArray) -
SurferOnWww さん の発言:.NETの中での定義はされていないかもしれませんが、ホワイトスペース等が出力されると期待するのは危険です。
> null文字は文字列の終端を意味する意図もあるので、それ以降の文字が表示さ
> れないといった現象として出てきています。どうもゼロは終端文字を意味するというわけではなくて、表示結果がどうなるか
は未定義ということではないのでしょうか?
SurferOnWww さん の発言:
Dim testArray As Byte() = {&H50, &H53, &H5A, &H5A, &H0, &H0, _ &H0, &H0, &H4E, &H4E, &H4E, &H4E, _ &H4E, &H4E, &H0, &H0} For i As Integer = 0 To testArray.Length - 1 ' 日本語の第2バイトか ASCII かは直前のバイトが 0x80 以上かどうかで判断。 If testArray(i) > &H7F Then i += 1 Continue For End If If testArray(i) < &H20 OrElse testArray(i) > &H7E Then testArray(i) = &H20 End If Next Dim sp As New EncoderReplacementFallback(" ") Dim df As New DecoderReplacementFallback(" ") Dim enc As Encoding = Encoding.GetEncoding("Shift_JIS", sp, df) TextBox1.Text = enc.GetString(testArray) 何をもって表示される・されないと判断するのが難しいとは思います。
0x80以上であればShiftJISの2バイトコードの先頭バイトと判断するのもリスキーです。
根拠: http://ja.wikipedia.org/wiki/Shift_JIS
>Shift_JISの2バイトコードの空間は、第1バイトが0x81-9Fならびに0xE0-0xFC、第2バイトが0x40-0x7Eならびに0x80-0xFCである。
参考になった返信には「回答としてマーク」のボタンを利用して、回答に設定しましょう(未解決の場合を除く)。