2

mmapを書いていた場合uint32_t、ビッグ エンディアン/リトル エンディアンの規則で問題が発生しますか? 特に、ビッグ エンディアン マシンでデータを書き込んだ場合、mmapリトル エンディアン マシンでそのデータを読み込もうとすると問題が発生しますか?

4

2 に答える 2

6

mmap を使用している場合、おそらく速度と効率が気になります。基本的にいくつかの選択肢があります。

  1. すべての読み取りと書き込みを htonl、htons、ntohl、ntohs 関数でラップします。Windows で htonl (ホストからネットワークへ) の順序を呼び出すと、データがリトル エンディアンからビッグ エンディアンに変換されます。他のアーキテクチャでは、それはヌープになります。これらの変換にはオーバーヘッドがありますが、操作によっては、重要な場合とそうでない場合があります。私の知る限り、これはSQLiteで使用されるアプローチです
  2. もう 1 つのオプションは、データを常にホスト形式で書き込み、ユーザーがプラットフォーム間でデータを移行する必要がある場合にルーチンを提供することです。データベースは通常、データをホスト形式で読み書きしますが、ASCII またはネットワーク バイト順で書き込む bcp などのツールを提供します。
  3. ファイルのヘッダーにバイト オーダー マークのタグを付けることができます。プログラムが起動すると、ファイルのバイト順と比較し、必要に応じて翻訳を提供します。これは、多くの場合、UTF-16 のような単純なデータ形式には適していますが、多数の可変長型がある形式には適していません。

さらに、長さのプレフィックスやファイル オフセットを提供するようなことを行うと、32 ビットと 64 ビットのポインターが混在する可能性があります。32 ビット プラットフォームでは 4 GB を超える mmap ビューを作成できないため、4 GB を超えるファイル サイズをサポートすることはほとんどありません。rrdtool などのプログラムはこのアプローチを採用しており、64 ビット プラットフォームでより大きなファイル サイズをサポートします。これは、ファイル内でプラットフォーム ポインター サイズを使用した場合、バイナリ ファイルがプラットフォーム間で互換性がないことを意味します。

私が推奨するのは、事前にすべてのバイト オーダーの問題を無視し、プラットフォームで高速に動作するようにシステムを設計することです。データを別のプラットフォームに移動する必要がある場合は、最も簡単/迅速/最も適切な方法を選択してください。プラットフォームに依存しないデータ形式を作成しようとすることから始めると、通常は間違いを犯し、後で戻ってそれらの間違いを修正する必要があります。これは、データの 99% が正しいバイト順であり、1% が間違っている場合に特に問題になります。これは、データ変換コードのバグを修正すると、すべてのプラットフォームで既存のクライアントが機能しなくなることを意味します。

複数のプラットフォームをサポートするコードを作成する前に、マルチプラットフォームのテスト セットアップを用意する必要があります。

于 2009-06-22T07:20:42.937 に答える
2

はい。

mmap生のファイル データをプロセス アドレス空間にマップします。生データが何を表しているかについては何も知りません。ましてや、変換を試みることはできません。エンディアンが異なるアーキテクチャで同じファイルをマッピングする場合は、必要な変換を自分で行う必要があります。

コンピューター間で移植可能なデータ形式として、データ形式を特定の実装に結び付けない、JSON や XML などの抽象化レベルの高いものを検討します。しかし、それは本当にあなたの特定の要件に依存します.

于 2009-06-22T07:19:23.393 に答える