c++ - 转换数据类型以添加​​到 QByteArray 以将原始数据写入文件

标签 c++ qt file serialization memcpy

我有一些数据类型要写入原始数据文件。我没有使用 QDataStream,因为它会写入一些关于数据的额外信息,比如数据的长度和顺序。我只想要一个只有我写入的字节的文件,并且只会由知道所写入数据类型的正确顺序和大小的人解释。

我正在使用 QFile,使用写入方法 qint64 QIODevice::write(const QByteArray &byteArray)

我有几个 uint8_t、uint32_t 和 float 要写入文件。如何将此数据转换为没有额外字节的 QByteArray?

这是我目前所拥有的:

void FileWriter::writeData(uint8_t status, uint8_t channel, uint32_t ticks, float source0, float source1){

    QByteArray dataToWrite;

    //some code to add the paramters to the dataToWrite array

    this->file.write(dataToWrite);
}

转换为 char 的常规旧样式给我一个implicit conversion changes signedness 错误,因此无法正确存储值。

将这些值复制到 QByteArray 以便我可以将其写入文件的正确方法是什么?

最佳答案

通常,您希望序列化数据流,同时注意数据的字节顺序。

uint8_t可以使用简单的 static_cast 将变量转换为字节.对于较大的整数类型,您需要跟踪数据的字节顺序,并逐字节推送。

float数据类型有点棘手。您首先需要将 float 的位表示为整数值 ( uint32_t ),然后从那里进行序列化。示例如下:

QByteArray data;

//serialize a uint8_t
data.push_back(static_cast<char>(status));

//serialize a uint32_t, little-endian
data.push_back(static_cast<char>((ticks) & 0xFF); //lowest-order byte
data.push_back(static_cast<char>((ticks >> 8) & 0xFF));
data.push_back(static_cast<char>((ticks >> 16) & 0xFF));
data.push_back(static_cast<char>((ticks >> 24) & 0xFF)); //highest-order byte

//serialize a float, by first representing the bits as a uint32_t: 

static_assert(sizeof(float) == sizeof(uint32_t), "Floats should be 4 bytes");
uint32_t rep;
std::memcpy(&rep, &source0, sizeof(float)); //using memcpy here so that we don't violate strict aliasing. 
data.push_back(static_cast<char>((rep) & 0xFF);
data.push_back(static_cast<char>((rep >> 8) & 0xFF));
data.push_back(static_cast<char>((rep >> 16) & 0xFF));
data.push_back(static_cast<char>((rep >> 24) & 0xFF));

this->file.write(data);

需要注意的几点:

  1. 数据的字节顺序很重要。并非所有系统都具有相同的字节顺序,因此您需要在文档中明确说明字节的定向方式。

  2. 有些人尝试转换 float 的位到 uint32_t通过写类似 uint32_t rep = *reinterpret_cast<uint32_t*>(&source0); 的东西.不要这样做——这违反了 Strict Aliasing Rule .

  3. 将版本号序列化为文件的第一部分可能是个好主意,这样您就可以在将来更改数据格式并使其向后兼容。

  4. 很多这种手动位打包都可以写入模板函数中,自动完成。这是留给读者的练习。

  5. 如果性能很重要,您应该弄清楚数据的大小和 reserve()推送之前字节数组中的空间——这将使数组免于重新分配和一遍又一遍地增长。

关于c++ - 转换数据类型以添加​​到 QByteArray 以将原始数据写入文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53090332/

相关文章:

c++ - 在派生类中作为模板实现的虚函数

c++ - C++ (Visual Studio 6) 中 operator< 和 operator[] 的默认返回值是什么?

c++ - 如何组成一个矩阵来执行世界坐标的等轴测(二轴测)投影?

c++ - 是否可以断开 QObject 的所有连接而不删除它

android - 如何从绝对路径检索视频缩略图?

c++ - OpenCV 和使用傅立叶变换 dft()

c++ - 如何禁用 QTextEdit 的中键功能?

c++ - Qt : After installation of VS2012 LNK1123 failure during conversion to COFF

c++ - 在 C++ 中解析 .dat 文件

C++ 从文件中获取数据以记住上次 session