3

私は趣味でゲーム プロジェクトをコーディングしています。現在、リソース データ (.BMP など) を独自のファイル形式に保存して、ゲームがそのすべてを解析し、スクリーン。

BMP を読み取るために、ヘッダーを読み取り、次に各ピクセルの RGB データを読み取り、これらの値を格納する配列 [幅] [高さ] を用意しました。

これらのタイプのデータをバイナリで保存する必要があると言われましたが、理由はありません。バイナリとその内容 (データの 0-1 表現) について読んだことがありますが、たとえば .BMP データを保存するためにそれを使用する必要があるのはなぜですか? ゲームの後半で読むつもりなら、複雑さが増すだけでなく、読み込みプロセスが遅くなるだけではありませんか?

最後に、バイナリで保存する方が良い場合 (私が他のゲーム リソース ファイルで調査したことから、誰もがそうしているように見えるので、そうであると推測しています)、C++ でバイナリを読み書きするにはどうすればよいですか? 私は多くの質問を見てきましたが、多くの異なるタイプの変数に対してさまざまな方法があるため、どの方法が最善の/よりC++っぽい方法であるかを尋ねていますか?

4

1 に答える 1

9

あなたはそれをすべて後方に持っています。コンピュータ プロセッサは、データをバイナリ レベルで処理します。コンピュータ内のすべてはバイナリです。人間が読める形式のデータを処理するために、バイナリ データを人間が理解できるように見せる関数を作成します。したがって、.BMP データをテキストとしてファイルに保存すると、.BMP データを自然なバイナリ形式からテキストに変換し、テキスト形式からバイナリに戻すために、実際にはコンピューターにさらに多くの作業を行わせることになります。表示するためです。

実際のところ、生のバイナリ形式でデータを処理できるほど、コードの実行速度が向上します。変換が少ないということは、コードが高速であることを意味します。ただし、明らかにトレードオフがあります。魔法のデコーダー リングを引き出さずにデータを見て理解できるようにする必要がある場合は、データをテキストとしてファイルに保存することをお勧めします。しかし、そうする際には、人間が読めるテキストをプロセッサにとって意味のあるものにするために行わなければならない変換処理があることを理解する必要があります。これは、先ほど述べたように、純粋なバイナリ データのみで動作します。


そして、あなたがすでにそれを知っていた、またはある程度知っていて、あなたの質問が「テキストモードではなくバイナリモードで .bmp ファイルを開く必要があるのはなぜですか」という場合に備えて、その理由はテキスト モードのファイルは、必要に応じてプラットフォームに CRLF から LF への変換 ("\r\n" から "\n" への変換) を実行するように要求し、内部の文字列処理レベルですべてのあなたが扱っているのは '\n' 文字です。ファイルがバイナリ データで構成されている場合、その変換を実行したくありません。そうしないと、ファイルを読み取るときにファイルからのデータが破損します。この状態では、ほとんどのデータは正常であり、ほとんどの場合正常に動作する可能性がありますが、変換される 16 進数形式 0x0d,0x0a (10 進数 13,10) のバイトのペアに遭遇することがあります。ちょうど 0x0a (10) に、読み取ったデータで 1 バイトが失われます。したがって、バイナリ ファイルは必ずバイナリ モードで開いてください。


OK、あなたの最新のコメント(以下)に基づいて、これがこれです:

ご存じのとおり、コンピューターのデータはバイナリ形式で保存されます。はい、それは 0 と 1 の中にあることを意味します。ただし、プログラミングの際、何らかの理由でビット単位の論理演算を行う場合を除き、実際に自分で 0 と 1 をいじる必要はありません。たとえば、タイプの変数はint、個々のビットのコレクションであり、それぞれが 0 または 1 のいずれかになります。これはバイトのコレクションでもあり、1 バイトに 8 ビットがあると仮定すると、通常は 2 ビットになります。 、4、または 8 バイト (intプラットフォームおよびコンパイラ オプションに応じて) 内。しかし、個々の 0 と 1 としてではなく、それをintとして扱います。intそう書くとint最も純粋な形式でファイルに出力すると、バイト (およびビット) は変換されていない生の形式で書き出されます。しかし、それらを ASCII テキストに変換して、そのように書き出すこともできます。画面に を表示している場合int、もちろん個々の 0 と 1 を見たくないので、通常は 10 進数としてデコードされた ASCII 形式で出力します。同じものを 16 進形式で簡単に出力できますint。同じ数値であっても、結果は異なって見えます。たとえば、10 進数では、10 進数の値 65 を使用できます。16 進数では、同じ値は 0x41 (基数 16 であることがわかっている場合は 41 のみ) です。ASCII 形式で表示すると、同じ値が文字 'A' になります (そして、2、- 4、または 8 バイトの下位バイトのみを考慮しますint。つまり、char)。

この議論の残りの部分では、 について話していることを忘れて、int今は について話していると考えてください。char、または 1 バイト (8 ビット)。同じ値、65、または 0x41、または「A」がまだあるとしますが、それを調べたいとします。その値をファイルに送信する場合は、生の形式で送信するか、テキスト形式に変換できます。生の形式で送信すると、ファイル内で 8 ビット (1 バイト) を占めます。ただし、テキスト形式でファイルに書き込みたい場合は、ASCII に変換します。実際の値 (この場合は 65) を書き込む形式に応じて、1、2 のいずれかを占めます。 、または 3 バイト。パディング文字なしで 10 進 ASCII で書きたいとします。値 65 は 2 バイトを使用します。1 つは「6」用で、もう 1 つは「5」用です。16 進形式で出力したい場合でも、先頭に "charは値 255 ( a の最大値char) です。ファイルに 10 進数の ASCII 形式で書き込むと、3 バイトかかります。しかし、同じ値を 16 進数の ASCII 形式で書き込んだ場合、16 進数の値 255 は 0xFF であるため、それでも 2 バイト (「0x」を前に付けている場合は 4 バイト) かかります。これを、その 8 ビット バイト ( char) を生のバイナリ形式で書き込む場合と比較してください。Acharは (定義により) 1 バイトを取るため、その値に関係なく、バイナリ形式のファイルの 1 バイトのみを消費します。

于 2013-02-01T16:14:41.937 に答える