質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

.NET Framework 3.5

.NET Framework-3.5は、NET Framework 2.0にアセンブリを追加(3.0も含む)したものをベースにしています。

Q&A

解決済

2回答

5768閲覧

C# バイナリデータの読み込み(先頭アドレスの取得)

DENQ

総合スコア19

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

.NET Framework 3.5

.NET Framework-3.5は、NET Framework 2.0にアセンブリを追加(3.0も含む)したものをベースにしています。

0グッド

0クリップ

投稿2016/08/31 02:25

編集2016/08/31 02:50

いつもお世話になっています。

バイナリデータの読み込みで躓いております。
ご教授お願いします。

.Net FreameWork 3.5
windows 8.1
C#

private static void GetDataDB(string DirPath) { const string VALID_KUBUN = "8101"; //ファイル指定 string InFilePath = FolderPath + @"\" + FilePath; InFilePath = InFilePath.Replace(@"\\", @"\"); FileInfo fi = new FileInfo(InFilePath); //ファイル読取り BinaryReader br = new BinaryReader(File.OpenRead(InFilePath), PickOutCommon.sjisEnc); br = new BinaryReader(File.OpenRead(InFilePath)); // 2048:ブロックサイズ int block_size = 2048; // 6:ブロックヘッダサイズ int block_head_size = 6; // 26:1データサイズ int data_size = 26; Dictionary<int, STR> data_dic = new Dictionary<int, STR>(); //競合防止用のMBアドレスリスト ArrayList mbaddlist = new ArrayList(); //読み取り開始位置 (先頭ブロック)ヘッダ飛ばし br.BaseStream.Position = block_size; for (; br.BaseStream.Position < fi.Length; ) { //読取り開始アドレス long read_posi = br.BaseStream.Position; //2048B ごと読取り byte[] bys = br.ReadBytes(block_size); //ブロックヘッダ(6B) int bys_posi = block_head_size; //ブロックデータ(26B)を出力 for (; bys_posi + data_size < block_size; bys_posi += data_size) { string mb_address = string.Format("{0:X2}{1:X2}{2:X2}00", bys[bys_posi + 19], bys[bys_posi + 18], bys[bys_posi + 17]); //アドレスリストを作成 long mbadd = Convert.ToInt64(mb_address, 16); if (!mbaddlist.Contains(mbadd)) { //未登録の場合、リストに追加 mbaddlist.Add(mbadd); } string kubun = string.Format("{0:X2}{1:X2}", bys[bys_posi + 6], bys[bys_posi + 7]); if (VALID_KUBUN.Equals(kubun) == false) { // 有効区分ではない continue; } int id = (bys[bys_posi + 2] * 0x100) + bys[bys_posi + 3]; int renban = bys[bys_posi + 5]; //ここから string timestamp = string.Format("{0:X2}{1:X2}{2:X2}{3:X2}", bys[bys_posi + 8], bys[bys_posi + 9], bys[bys_posi + 10], bys[bys_posi + 11]); if (data_dic.Keys.Contains(id)) { string new_comp_key = string.Format("{0}_{1:D2}_{2}", timestamp, renban, mb_address); string old_comp_key = string.Format("{0}_{1:D2}_{2}", data_dic[id].TIMESTAMP, data_dic[id].RENBAN, data_dic[id].MB_ADDRESS); int comp_rst = string.Compare(new_comp_key, old_comp_key); if (comp_rst <= 0) { continue; } else { data_dic.Remove(id); } } //ここまでが不具合を出してる部分だと思われる STR data_db = new STR(); data_db.ADDRESS = string.Format("{0:X8}", read_posi + bys_posi); data_db.ID = id; data_db.RENBAN = renban; data_db.MB_ADDRESS = mb_address; data_db.data_sizeDB = BitConverter.ToUInt32(bys, bys_posi + 20); data_db.TIMESTAMP = timestamp; data_db.by00 = bys[bys_posi + 0]; data_db.by01 = bys[bys_posi + 1]; data_db.by02 = bys[bys_posi + 2]; data_db.by03 = bys[bys_posi + 3]; data_db.by04 = bys[bys_posi + 4]; data_db.by05 = bys[bys_posi + 5]; data_db.by06 = bys[bys_posi + 6]; data_db.by07 = bys[bys_posi + 7]; data_db.by08 = bys[bys_posi + 8]; data_db.by09 = bys[bys_posi + 9]; data_db.by10 = bys[bys_posi + 10]; data_db.by11 = bys[bys_posi + 11]; data_db.by12 = bys[bys_posi + 12]; data_db.by13 = bys[bys_posi + 13]; data_db.by14 = bys[bys_posi + 14]; data_db.by15 = bys[bys_posi + 15]; data_db.by16 = bys[bys_posi + 16]; data_db.by17 = bys[bys_posi + 17]; data_db.by18 = bys[bys_posi + 18]; data_db.by19 = bys[bys_posi + 19]; data_db.by20 = bys[bys_posi + 20]; data_db.by21 = bys[bys_posi + 21]; data_db.by22 = bys[bys_posi + 22]; data_db.by23 = bys[bys_posi + 23]; data_db.by24 = bys[bys_posi + 24]; data_db.by25 = bys[bys_posi + 25]; data_db.st26B += string.Format("{0:X2} {1:X2} {2:X2} {3:X2} {4:X2} {5:X2} {6:X2} {7:X2} {8:X2} {9:X2} {10:X2} {11:X2} {12:X2} {13:X2} {14:X2} {15:X2} {16:X2} {17:X2} {18:X2} {19:X2} {20:X2} {21:X2} {22:X2} {23:X2} {24:X2} {25:X2}", data_db.by00, data_db.by01, data_db.by02, data_db.by03, data_db.by04, data_db.by05, data_db.by06, data_db.by07, data_db.by08, data_db.by09, data_db.by10, data_db.by11, data_db.by12, data_db.by13, data_db.by14, data_db.by15, data_db.by16, data_db.by17, data_db.by18, data_db.by19, data_db.by20, data_db.by21, data_db.by22, data_db.by23, data_db.by24, data_db.by25); data_dic.Add(id, data_db); } } data.DBファイルのデータ構造体 public struct STR { public string ADDRESS; public int ID; public int RENBAN; /// <summary>0:未判定、1:有効、2:無効 連番から判定した有効フラグ</summary> public int RENBAN_FLG; public string MB_ADDRESS; public uint data_sizeDB; public int data_size; public string st26B; public string TIMESTAMP; public byte by00; public byte by01; public byte by02; public byte by03; public byte by04; public byte by05; public byte by06; public byte by07; public byte by08; public byte by09; public byte by10; public byte by11; public byte by12; public byte by13; public byte by14; public byte by15; public byte by16; public byte by17; public byte by18; public byte by19; public byte by20; public byte by21; public byte by22; public byte by23; public byte by24; public byte by25; public string block_head; public byte head_by00; public byte head_by01; public byte head_by02; public byte head_by03; public byte head_by04; public byte head_by05; }

上記が現状で動いてるものです。

データの中からそれぞれ、バイナリの先頭アドレス、ID、連番などを取得しています。
データの中には同じIDのデータが複数入っており、最新の先頭アドレスと連番等を取得したいです。
現在、一部のデータ(mb_address)が最新ではない物になっているため、その後の処理に影響が出ています。

したい事

データ内から最新の情報を取得したい。
特にmb_addressの部分。(これが先頭アドレスになるのでここが間違えると後の処理で正確なデータが採取できなくなる。)

謎な部分。
作成者のコメント欄には TIMESTAMPは大きい数字が最新。と言う表記があるが16進数の比較が不明
実際の比較は timestamp, renban, mb_addressの文字列で比較をしていて0以下であればにコンテニュー1以上であればディクショナリーを削除して再登録
ただ、この比較では本当に最新の情報を取得できているか不明。

バイナリの処理は初めてなので不明点が多すぎて困っております。
皆さまご教授の程よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

moonphase

2016/08/31 02:30

コードは見やすくするために上下を ``` (バッククォート3つ)で囲ってください。 質問を読みましたが、何が問題なのかいまいちわかりません。 また、「最新のレコード(データ)」が欲しいとありますが、最新のレコードは何を以って判定しますか?
DENQ

2016/08/31 02:49

データの最新の判断は TIMESTAMPは大きい数字が最新 と前任者のコメントがあったのでtimestampだと思います。 ただ実際の比較は下記のようにされてます。 string new_comp_key = string.Format("{0}_{1:D2}_{2}", timestamp, renban, mb_address); string old_comp_key = string.Format("{0}_{1:D2}_{2}", data_dic[id].TIMESTAMP, data_dic[id].RENBAN, data_dic[id].MB_ADDRESS); int comp_rst = string.Compare(new_comp_key, old_comp_key); if (comp_rst <= 0) { continue; } else { data_dic.Remove(id); } ですが、このプログラムだと一部のidが最新情報が取れてない為、のちの処理に影響が出ている状況です。
guest

回答2

0

自己解決

バイナリをブロックごとに分けて計算してましたが、ソフトを使ってaccessのデータベースにしてそれから読み込むようにしたら、解決できました。
皆さま協力ありがとうございました。

投稿2016/09/09 06:57

DENQ

総合スコア19

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

読み込み後data_dicからとあるidのデータを取ってきたら最新のデータを示していなかった、ってことですかね?
気になるのはエンディアンが混在しているようです。
timestampはビッグエンディアンになっているようですが書き出し側はこれであっているんでしょうか?

余談ですが、タイムスタンプが新しいのに連番が古いなんてこと起こり得るんでしょうか?
連番が同じでmbaddressが違うようなデータが存在するんでしょうか?
連番はまぁいいとして少なくともアドレスは比較に含める意味がないように思いますが、、、

投稿2016/09/02 03:48

toki_td

総合スコア2850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問