C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: 指定範囲のバイナリデータの読み込み


(過去ログ 126 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■75083 / inTopicNo.1)  指定範囲のバイナリデータの読み込み
  
□投稿者/ ART (1回)-(2015/02/25(Wed) 14:08:58)

分類:[VB.NET/VB2005 以降] 

お世話になります、ARTです。
---
Windows7 64Bit
VisualBasic 2008 EE
---

現在、以下の様な処理を行うプログラムを作成しようと試行錯誤をしておりますが、
バイナリデータを扱う事自体が初めてなので、アドバイスをお願い致します。

1.OpenFileDialogでファイルを選択。

2.BinaryReaderクラスを使用し、バイナリデータとして読み込む。

3.指定したアドレス範囲のデータを読み込む。

4.読み取ったデータをShift-Jis形式でテキストボックスに表示。

(終)

例えば、16ビットのデータにて
「0x0120」から「0x012F」に以下のようなデータがあるとします。

42 48 4E 00 00 00 00 00 00 00 00 00 00 00 00 00

このとき、「0x0120」から「0x0122」までを読み込んで、
テキストボックスに「BHN」と表示させたいと考えております。
(「0x012F」まで読み込んで、空欄を除外するのも良い?)


現状、1〜2までは出来たのですが、3〜4のステップが分かりません。
どなたかご教示下さいますようお願い致します。

宜しくお願い致します。



引用返信 編集キー/
■75086 / inTopicNo.2)  Re[1]: 指定範囲のバイナリデータの読み込み
□投稿者/ 魔界の仮面弁士 (213回)-(2015/02/25(Wed) 15:57:19)
No75083 (ART さん) に返信
> 現在、以下の様な処理を行うプログラムを作成しようと試行錯誤をしておりますが、
> バイナリデータを扱う事自体が初めてなので、アドバイスをお願い致します。

データ量がさほど多くないのであれば、こんな風にも書けます。


'全部読み出した上で、その中から 0x120〜0x12F までを切り出す
Dim entry = System.IO.File.ReadAllBytes(fileFullPath).Skip(&H120).Take(&HF)

'末尾に 0x00 があれば、それ以降のデータを捨てる
Dim binary() As Byte = entry.TakeWhile(Function(b) b > 0).ToArray()

'取得したバイナリを ASCII 値とみなして表示
TextBox1.Text = System.Text.Encoding.ASCII.GetString(binary)


> 2.BinaryReaderクラスを使用し、バイナリデータとして読み込む。
> 3.指定したアドレス範囲のデータを読み込む。

ファイルサイズが大きい場合には、確かに BinaryReader を使った方が良いでしょうね。


> 現状、1〜2までは出来たのですが、3〜4のステップが分かりません。
BinaryReader に引き渡した元ストリーム(BaseStream)に対して、
Seek メソッド または Position プロパティで読み取り位置を変更してみて下さい。

もしくは、BinaryReader の ReadBytes メソッドを使って、
0x120 に至るまでの余剰部分を読み捨てればよいかと。


> 4.読み取ったデータをShift-Jis形式でテキストボックスに表示。
これは本回答の冒頭サンプルに書いた、Encoding クラスを使うのが良さそうです。


> テキストボックスに「BHN」と表示させたいと考えております。
> (「0x012F」まで読み込んで、空欄を除外するのも良い?)
0x00 な文字は TextBox には表示されず、それ以降が切り捨てられるはずなので、
00 以降を検出する処理は省いても、それなりに動作するかも。(手抜き実装)
引用返信 編集キー/
■75087 / inTopicNo.3)  Re[2]: 指定範囲のバイナリデータの読み込み
□投稿者/ ART (2回)-(2015/02/25(Wed) 16:59:50)
>魔界の仮面弁士 さま

アドバイス有難うございます!
「Seekメソッド」と「Encodingクラス」を使用して、以下のようなコードで、目的のデータが取得出来ました。

<--- Code Start --->
        '16進数文字列に変換
        Dim myStartHex = Val(myStartPos)

        Using Stream As System.IO.Stream = System.IO.File.OpenRead(myfilePath)
            'ファイルの読取り開始位置をシーク
            Stream.Seek(myStartHex, IO.SeekOrigin.Begin)
            'バイナリ読み込み
            Using Reader As New System.IO.BinaryReader(Stream)
                ' ストリームから指定バイト読み込みバイト配列として取得する
                Dim Data() As Byte = Reader.ReadBytes(myBitCount)

                'Shift-JISにエンコード
                Dim sjisEnc As System.Text.Encoding = System.Text.Encoding.GetEncoding(932)
                myBinary = sjisEnc.GetString(Data)

            End Using
        End Using
<--- Code End --->

モジュールとして作成しており、引数に
・ファイルパス(myfilePath)
・読取り開始アドレス(myStartPos)(「&H120」の形式)
・読み取るアドレス数(myBitCount)
・返り値(myBinary)
を指定します。


動作的には問題ないかと思うのですが、修正点があればご教示頂けると幸いです。


引用返信 編集キー/
■75089 / inTopicNo.4)  Re[3]: 指定範囲のバイナリデータの読み込み
□投稿者/ shu (697回)-(2015/02/26(Thu) 08:36:57)
No75087 (ART さん) に返信
> '16進数文字列に変換
16進数文字列を整数(integer)に変換


> Dim myStartHex = Val(myStartPos)
変数名が16進数を意識しているようですが中身はintegerなので適切でない


> ' ストリームから指定バイト読み込みバイト配列として取得する
> Dim Data() As Byte = Reader.ReadBytes(myBitCount)
バイト数なのでBitCountよりはByteCountの方がよいかも


>
> 'Shift-JISにエンコード
> Dim sjisEnc As System.Text.Encoding = System.Text.Encoding.GetEncoding(932)
> myBinary = sjisEnc.GetString(Data)
文字列を求めているのでShift-JISでデコードが正しい
文字列を求めているのでmyBinaryだと分かりにくい



引用返信 編集キー/
■75090 / inTopicNo.5)  Re[4]: 指定範囲のバイナリデータの読み込み
□投稿者/ ART (3回)-(2015/02/26(Thu) 09:19:09)
shu さま

アドバイス有難うございます!
理解不足による文言や変数名の間違いが多く、お恥ずかしい限りです...(・・;)

> 16進数文字列を整数(integer)に変換
> 変数名が16進数を意識しているようですが中身はintegerなので適切でない
> バイト数なのでBitCountよりはByteCountの方がよいかも
> 文字列を求めているのでShift-JISでデコードが正しい
> 文字列を求めているのでmyBinaryだと分かりにくい

上記、ご指摘のように修正させて頂きました。
魔界の仮面弁士さま、shuさま。 アドバイス有難うございました。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -