QDataStreamでバイナリをファイルに書き出すときの問題
Qtではテキストなどを書き込むにはQTextStreamなどを使いますが、バイナリを書き込むときは、それ方法だと一部のバイナリが正常に書き出されません。
そこで代わりにQDataStreamを使ってファイルにバイナリを書き出そうとするとある問題が生じます。
例えば次の例を見てください。
QByteArray data = QString("48656c6c6f").toUtf8().toHex(); /// 書き込むバイナリデータ QFile file("[File path]"); file.open(QFile::ReadWrite); QDataStream ds(&file); ds.setVersion(QDataStream::Qt_5_1); ds >> data; file.close();
一見するとこれでファイルにバイナリが正しく書き込まれるように思えます。
確かにバイナリは正しく書き込まれますが、実際にファイルをバイナリエディタで見ると内容は次のようになっています。
ファイルのバイナリエディタでの表示00 00 00 05 48 65 6c 6c 6f
元のデータに加え先頭に4バイトが追加されています。この 00 00 00 05 はデータのサイズを表しています。
これはQDataStreamの仕様でデータを書き込むと必ず先頭に元のデータのサイズが追加されるようになっています。
なぜこのような仕様になっているかというとQDataStreamは元々データを直列化するためのものだからです。
これはデータを直列化するには便利ですが、バイナリデータを書き込む(バイナリエディタなどを作る)場合には正しくデータが書き込まれないことになります。
なのでバイナリデータをそのままファイルに書き込む際にはQDataStreamを使わずにQIODeviceのwrite関数を使うのが一番適しています。
QByteArray data = QString("48656c6c6f").toUtf8().toHex(); QFile file("[File path]"); file.open(QFile::ReadWrite); file.write(data); file.close();
結論としてはデータの直列化するときだけQDataStreamを使い、ファイルにバイナリを書き込むときは使わない方がいいということです。
関連項目
© Kaz