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

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

ただいまの
回答率

88.10%

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

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,665

score 19

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

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

.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以上であればディクショナリーを削除して再登録
ただ、この比較では本当に最新の情報を取得できているか不明。

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • moonphase

    2016/08/31 11:30

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

    キャンセル

  • DENQ

    2016/08/31 11: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が最新情報が取れてない為、のちの処理に影響が出ている状況です。

    キャンセル

回答 2

check解決した方法

0

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 88.10%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る