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

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

新規登録して質問してみよう
ただいま回答率
85.48%
アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Q&A

解決済

6回答

6006閲覧

バイナリファイルの区切り文字(厳密には"どうやって複数のデータを表現するか")

BeatStar

総合スコア4958

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

0グッド

0クリップ

投稿2018/10/24 01:38

編集2018/10/24 01:52

プログラミングにはあまり関係がありませんが... (タグは近いのが無いので...)

ゲームでインストーラ式のものがありますよね。

構成が

+ install.exe + setup.bin + readme.txt

のようになっているものです。

私のイメージではinstall.exe が setup.bin をバイナリモードで読み込み、
その生成しているイメージです。

例えば 区切り文字を '\S' ( separator ) とします。

[setup.bin]

struct + /data/ + /image/ + image1.src + image2.src + main.exe + readme.txt main.exe (ここにmain.exeのバイナリデータ) \S image1.src (ここにimage1.srcのバイナリデータ) \S image2.src (ここにimage2.srcのバイナリデータ) \S readme.txt ゲーム名.exe\nこのゲームは... \S

のような感じで、C言語でもなんでもいいですが、
言語のバイナリファイルを読み込むクラス,関数等で「1バイトずつ」読み込んで...

ってやっているのでしょうか?

それとも単純に、項目名(構成,それぞれのファイルのやつ) を"[]" でくくって、

[struct] + /data/ + /image/ + image1.src + image2.src + main.exe + readme.txt

のようにして、[struct] と 次の [] である [main.exe] までの位置を一つの文字列 (または1バイトずつ)
読み込んで書き込んでいるのでしょうか?

私はC++で組んでいますが、あまりバイナリファイルは扱っていません。
(最近扱い始めたばかりです。)

読み込み・書き込みはいいとして、使い方が単にテキストファイルのサイズが小さい版という感じです。
(本来は違うと思いますが...)

もし(表現自体はどうあれ)私がイメージした通りでしたら私の表現方法が広くなるかもしれないので...

私が使う言語はC++ ( better-C )ですが、言語自体に言及しないのであればどの言語でも構いません。

[情報]
基本的な言語: C++ ( and Qt )
頑張れば読めるかもしれない言語: Java, Python(?)
OS: Windows系 (XP,7,10) (表現がOSによって異なるかもしれないし...実行ファイルとかみたいに)

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

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

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

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

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

guest

回答6

0

ベストアンサー

バイナリファイルの構造は、作者が自由に決められます。ただし、データの中にどんなバイトも現れうるので、「特定のバイト」を区切り文字にするような方式はあまり使われません。

よくあるパターンとしては、

  • データ先頭部のヘッダにデータ自体の長さも入れてある
  • インデックスデータが最初に用意してあって、本体はそこからオフセットで参照される

などがあります。

投稿2018/10/24 01:42

maisumakun

総合スコア145183

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

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

BeatStar

2018/10/24 01:51

ご回答ありがとうございます。 やはり特定のバイトは区切り文字にしませんよね... 私が悩んでいたのはそこでした。0 を区切り文字にしても 0 が(ファイルや"構造"等のような)データ上に現れる可能性もあるし、\S とかでもそうですし... データ先頭にデータ自体の長さを入れる... 多分 514129 とあったら 長さ5 の "14129" っていうことですよね? でも、もう一方の"インデックスデータが最初に用意してあって..."がちょっとイメージできません。 なんかイメージできそうな、質問でのsetup.binの内部みたいな感じで簡易的でもいいので、提示していただけませんか?
guest

0

中身を覗かれても問題なければ、*.binと言いつつ実際にはzipファイル、などにしておけば圧縮ファイルの展開用コードを組み込むだけで済みます。

自分専用形式にしたいのであれば、まずはそういったファイルのフォーマットを調べてみるとか。

ZIP (ファイルフォーマット)

投稿2018/10/24 01:59

daisuke7

総合スコア1563

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

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

maisumakun

2018/10/24 02:00

jarとかapkとかOOXMLとか、「特殊なデータ配置にしたZipファイル」形式のものもよく見かける気がします。
daisuke7

2018/10/24 03:36

そうですね。ipaとかもですし、結構多いと思います。
BeatStar

2018/10/26 00:45

ご回答ありがとうございます。 なるほど。zipとかをまねて...ですか。 ちょっと試してみます。
guest

0

こんにちは。

どうもバイナリ・ファイルをうまくイメージできていないように見受けられます。
テキスト・ファイルは基本的に可読文字のみで構成されますが、バイナリ・ファイルには普通は全てのコードが入りますから、それをテキストとして表示すると文字化けしまくりです。

例えば、hello worldをビルドした exe をtype(後半略)すると、

> type hello.exe MZ・    ク @ ・ コ エ ヘ!クLヘ!This program cannot be run in DOS mode. $ PyJイ$・$・$・`キ・$・~'・$・~!・$・~ ・$・~%・$痣|%・$・%・$・!・$・ロ・$・&・$甞ich$・

これを16進数でダンプ(後半略)すると、

00000000 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 00000010 B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000030 00 00 00 00 00 00 00 00 00 00 00 00 F0 00 00 00 00000040 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68

このようにバイナリ・ファイルの中身をテキストとして表示すると文字化けしますので、文字列としてではなく、16進数等で表記することが多いです。
なお、型が明確なデータに関しては、その部分だけ10進数で表記したり、文字列で表記したりすることもあります。

投稿2018/10/24 02:18

Chironian

総合スコア23272

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

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

BeatStar

2018/10/28 01:28

ご回答ありがとうございます。 もうちょっと調べてみますね。
guest

0

maisumakunさんの回答で良いと思いますが、
特定のバイトを区切り文字にするような方式はあまり使われないものの無いわけではないので補足しますと、
データ中に現れうる値を区切り文字に使う場合、データ中の当該の値を別のものに置き換える対処が一般的です。
例えばJPEGは0xFFを区切り文字に使いますが、データ中の0xFFは0xFF 0x00の2バイトに置き換えます。

投稿2018/10/24 05:00

ikadzuchi

総合スコア3047

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

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

BeatStar

2018/10/28 01:29

ご回答ありがとうございます。 なるほど。置き換えでダブらないように工夫...ですか。
guest

0

バイナリファイルはなんでもありです。
簡単には、

C

1 struct hoge { 2 int a; 3 char b[100]; 4 short c; 5 .... 6 } 7 struct hoge hoge1; 8 struct hoge hoge2; 9 10 .... 11 FILE *fp1 = fopen("FileName1", "rb"); 12 FILE *fp2 = fopen("FileName2", "wb"); 13 14 .... 15 fwrite((char *)&hoge1, sizeof(struct hoge), 1, fp1); 16 .... 17 fread((char *)&hoge2, sizeof(struct hoge), 1, fp2); 18 .... 19

なんて使い方もありですね。
(hoge1 のデータをファイルに出力。hoge2 にファイルから読込み)

構造体だと、アライメントの問題とか言われますが、同じプログラムで読み書きする分には問題有りません。この方法で、内部データをファイルに保存する方法もありです。(メンテナンスが大変なので、お奨めではありませんが)

良くあるのが、

C

1 int data1; 2 fwrite(&data1, sizeof (int), 1, fp);

などとし、データを一つずつ、ファイルに出力し、読出しは、同じ順序で行うものです。(こちらもメンテナンス大変ですが、変更しないという前提ならば、簡単)

例にある install.exe がsetup.binを読み込む件は、install.exeがどうしているかなので、作った人に聞くしかないですが、daisuke7さんの書かれたように、zip形式で圧縮もありですね。頭に余分なヘッダを付けて、renameだけでは展開できないようにとか、拘るところもあるようですが。あるいは、専用の展開モジュールを付加するのもあるようです。

投稿2018/10/24 12:02

pepperleaf

総合スコア6383

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

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

BeatStar

2018/10/28 01:29

ご回答ありがとうございます。 なるほど。やはりzipとかで...でしょうか。
guest

0

皆様、ご協力ありがとうございました。
皆様の回答が素晴らしく、(どれをベストアンサーにすべきか)ものすごく迷いましたので
真っ先に回答してくださったmaisumakunさんをベストアンサーに選びたいと思います。
( できるなら皆様 全員にベストアンサーに選びたいところですが、機能的に... )

問題に関しましては、もうちょっと皆様のお考えをもとにして自分なりのものを考えてみようと思います。

投稿2018/10/28 01:34

BeatStar

総合スコア4958

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問