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

バイナリファイル内のテキストデータの抽出

環境/言語:[Windows Xp/VB2008]
分類:[.NET]

はじめて、Visual Basic 2008 Express Editionでアプリを作成しています。

複数の商品コードがテキストで埋め込まれいるバイナリファイルが800個ほど
あります。ファイルには次のように色々なデータ型が混在して入っています。
それぞれの位置は一定ではありません。
(1) バイナリデータ 例);^Aー"^]^P^B^@^@^@..
(2) 商品名 例)リポビタンD100mlのように2バイトと1バイト文字列が混在
(3) 商品コード 例)I10130
このファイルの中から(3)商品コードを抜き出してファイル名と商品コードの一覧
をCSVファイルに出力するアプリを作ろうとしています。ファイルサイズは最大でも
40,000バイトです。
フォルダの指定やファイルリストの取得はできました。その後の処理で行き
詰まっています。
教えていただきたいことは、ファイルの読み込み方法とその後の抽出方法です。
(1) ファイルを全部バイト配列に読み込んでから、商品コードを抽出した方が
よいか
  それともファイルを1バイトずつ読み込んだ方がよいか
  BinaryReader、StreamReaderのどちらを使うのかもわかりません。
(2) 全部バイト配列に読み込んだときのバイト配列内のテキストデータの
検索・抽出方法

Basicと言えば、20年も前にN88-BASICで仕事用のデータベースを組んだことしか
ありませんので、最近のオブジェクト指向にはなかなか馴染めません。
初歩的な質問をするかもしれませんが、よろしくお願いします。
■No25352に返信(おにいさんの記事)
> (1) バイナリデータ 例);^Aー"^]^P^B^@^@^@..
> (2) 商品名 例)リポビタンD100mlのように2バイトと1バイト文字列が混在
> (3) 商品コード 例)I10130

  このバイナリ部・商品名部・商品コード部を区分けする
  方法(仕様)が、記述されてません。

  それが解らない限り、抽出することはほぼ無理かと・・・

以上。
■No25353に返信(オショウさんの記事)
オショウさん、早速のご回答ありがとうございます。

>   このバイナリ部・商品名部・商品コード部を区分けする
>   方法(仕様)が、記述されてません。
バイナリ部と商品名部の区分けはわかりませんが、商品コードは
"I"で始まり5桁の数字と決まっています。

テキストエディタで開くと商品コードと商品名が読み取れるので
(1) バイト配列に読み込む
(2) "I"を探す
(3) "I"以降の5バイトを抽出する。
素人考えで作ってみたのですが、バイト配列そのままでは"I"を
探せないことがわかりました。文字列変数に変換する関数とか
何か方法があるのでしょうか。
よろしくお願いします。
■No25358に返信(おにいさんの記事)
> バイナリ部と商品名部の区分けはわかりませんが、商品コードは
> "I"で始まり5桁の数字と決まっています。

  いや、だからバイナリ部にも『I』が存在する可能性もあるし
  商品名部にも『I』があるかもしれない。

  ただ、『I』以降の5バイト分が、数字と言うことなので、
  『I』以降の5バイトを文字列として変数に代入し・・・

  Integer.Perse(dt) とかして、
  エラーしたら、商品コードではない
  正常に変換できたら、商品コードとする

  と言う方法で行えば、まずよいのでは?

  例外があるかどうかは、データ次第かと・・・

  それとバイト配列に読み込むより、MemoryStreamに全て読み込んで
  ストリームから読み出せば速度も速いので楽じゃ〜ない?

以上。
念のためですが、5 バイト取り出して評価した結果、数値列でなかった場合、最初の I を検出した次のバイトから再評価になります。
可能性があるかどうかは分かりませんが、III12345 というケースも想定されるためです。

あとは既に指摘されているように、バイナリ部や商品名部に I から始まる 5 桁の数値が現れる可能性があるかどうかですね。


■No25359に返信(オショウさんの記事)
>   それとバイト配列に読み込むより、MemoryStreamに全て読み込んで
>   ストリームから読み出せば速度も速いので楽じゃ〜ない?
「速度が速い」とする根拠を教えて頂けないでしょうか。
> 素人考えで作ってみたのですが、バイト配列そのままでは"I"を
> 探せないことがわかりました。文字列変数に変換する関数とか
> 何か方法があるのでしょうか。

商品コードの文字コードは何ですか?
(コードなのでたぶんASCIIコードでしょうけど)

文字コードの値を求めて、その値をバイト配列から探せばよいかと。
半角のIは、ASCIIコードやShift_JISなら、&H49ですので、
これを検索することになります。

文字コードがASCIIなら、Asc関数で文字コードを取得できます。
#他の文字コードならEncodingクラスのGetBytesメソッドを使います。
返事が遅くなり申し訳ありません。

■25359
オショウさん、ありがとうございます。
ファイルの中をビューワーで見て例外がないことがわかりましたので、
うまくいきそうです。
》それとバイト配列に読み込むより、MemoryStreamに全て読み込んで
》ストリームから読み出せば速度も速いので楽じゃ〜ない?
FileStreamメソッドさえよく理解ができていないので、MemoryStream
まで行き着きそうにありません。速度が問題なるようでしたらチャレンジ
してみます。


■25360
Azuleanさん、ありがとうございます。
》数値列でなかった場合、最初の I を検出した次のバイトから再評価になります。
ご指摘のミスを犯していましたので修正しました。

■25364
よねKENさん、ありがとうございます。
》#他の文字コードならEncodingクラスのGetBytesメソッドを使います。
このメソッドを使うと、いろいろなコード体系の文字が得られるのですね。
勉強になりました。

とりあえず、何とかなりそうですので、解決済みとさせていただきます。
みなさん、ありがとうございました。
解決済み!

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