1

uint8_tシリアル化してファイルに書き込みたいタイプの変数があります(少なくともWindowsでは、これは私が目指しているものであり、移植性が高いはずです)。

バイナリ形式でファイルに書き込もうとすると、次の作業スニペットに出くわしました。

uint8_t m_num = 3;
unsigned int s = (unsigned int)(m_num & 0xFF);
file.write((wchar_t*)&s, 1); // file = std::wofstream

まず、このスニペットが何をするのかを理解していることを確認させてください - それは私の var (基本的に unsigned char で、長さは 1 バイトです) を受け取り、それをunsigned int(4 バイトの長さで、あまり移植性がありません) に変換し、 & 0xFF "最下位バイトのみを抽出します。

今、私が理解していないことが2つあります:

  1. なぜそれを最初に変換するunsigned intのですか、なぜ単に or のようなことをできないのです
    file.write((wchar_t*)&m_num, 1);reinterpret_cast<wchar_t *>(&m_num)? (参照)
  2. より長いタイプ、たとえば a uint64_t(8 バイトの長さ) をシリアル化するにはどうすればよいですか? unsigned intここで十分かもしれませんし、十分でないかもしれません。
4

2 に答える 2

1

uint8_tと同じ 1 バイトです。char

wchar_tWindows では 2 バイト、Linux では 4 バイトです。また、エンディアンにも依存します。wchar_t移植性が懸念される場合は避けるべきです。

あなたはただ使うことができますstd::ofstreamstd::ofstreamWindows には、 UTF16 ファイル名を受け入れる追加バージョンがあります。このようにして、コードは Windows UTF16 ファイル名と互換性があり、引き続きstd::fstream. 例えば

int i = 123;
std::ofstream file(L"filename_in_unicode.bin", std::ios::binary);
file.write((char*)&i, sizeof(i)); //sizeof(int) is 4
file.close();
...
std::ifstream fin(L"filename_in_unicode.bin", std::ios::binary);
fin.read((char*)&i, 4); // output: i = 123

整数のみを格納するため、これは比較的単純です。Windows は常にリトルエンディアンであり、intサイズは常に 4 であるため、これはさまざまな Windows システムで機能します。

ただし、一部のシステムはビッグエンディアンであるため、個別に処理する必要があります。

たとえば、標準 I/O を使用する場合fout << 123456、整数はテキスト "123456" として格納されます。標準 I/O は互換性がありますが、必要なディスク容量が少し多くなり、速度が少し遅くなる可能性があります。

互換性とパフォーマンスです。大量のデータ (数メガバイト以上) があり、将来互換性の問題に対処できる場合は、バイトの書き込みに進みます。それ以外の場合は、標準 I/O を使用する方が簡単です。通常、パフォーマンスの違いは測定できません。

于 2016-06-11T10:08:15.350 に答える
0

aはワイド文字のみを書き込み、バイナリ値をまったく処理しないため、 aunit8_tに値を書き込むことはできません。wofstreamwofstream

0 ~ 255 のコード ポイントを表すワイド文字を書きたい場合、そのコードは正しいです。

バイナリ データをファイルに書き込みたい場合、最も近いものは ですofstream。これにより、バイトを書き込むことができます。

質問に答えるには:

  1. wofstream::writeバイトではなく、ワイド文字を書き込みます。のアドレスをワイド文字のアドレスとして再解釈するm_numと、16 ビットまたは 32 ビット (プラットフォームによって異なります) のワイド文字を書き込むことになります。プラットフォーム上) は の値でm_numあり、残りのバイトは の後にメモリ内で発生したものm_numです。ワイド文字の文字エンコーディングによっては、これは有効な文字ではない場合もあります。たとえ有効であったとしても、それはたいていナンセンスです。wofstream::write(バイト境界ではなくワイド文字境界で整列された入力を期待する場合、またはm_num読み取り不能なメモリが直後に続く場合は、他の問題が発生する可能性があります)。

  2. もしあなたがそれを使うならwofstream、これはめちゃくちゃです、そして私はそれに対処しません. バイト指向に切り替える場合、ofstream2 つの選択肢があります。1.同じシステムでファイルを読み取るだけの場合は、機能しますfile.write(&myint64value,sizeof(myint64value))。64 ビット値のバイトが書き込まれる順序は定義されていませんが、読み返すときに同じ順序が使用されるため、これは問題ではありません。危険ですので類似行為はしないでください!2. 8 バイトのそれぞれを個別に抽出し (8 ビットの倍数だけ右にシフトしてから下位 8 ビットを取得)、それを書き込みます。バイトが書き込まれる順序を制御するため、これは完全に移植可能です。 wofstreammyint64value

于 2016-06-11T11:36:11.207 に答える