【问题标题】:Qt: Write Struct to FileQt:将结构写入文件
【发布时间】:2017-09-18 15:57:00
【问题描述】:

我正在努力通过 Qt 中的 QFilestruct 写入文件。

typedef struct {
    uint32_t timestamp;
    uint32_t recordType;
    uint32_t payloadLength;
    char* payload;
} DataPacket;

DataPacket 结构在其他地方填充:

QString dataString = "$GPGSA,M,3,03,23,22,19,17,01,09,31,12,,,,1.9,0.9,1.6*3D";

DataPacket p;
memset(&p, 0, sizeof(DataPacket));
p.timestamp = now();
p.recordType = 1;
QByteArray arr = dataString.toLatin1();
p.payloadLength = arr.count();
p.payload = arr.data();

// Write the data to a log file
QFile f;
f.setFileName(outputFile);
bool ok = f.open(QIODevice::WriteOnly);

if (ok) {
    f.write((char *)&p, sizeof(DataPacket));
    f.close();
}

当我检查outputFile 日志文件时,找不到$GPGSA... 字符串。如果我再单独写payload字段:

if (ok) {
    f.write((char *)&p, sizeof(DataPacket));
    f.write(p.payload, p.payloadLength);
    f.close();
}

$GPGSA 字符串随后被正确写入。

我错过了什么......

【问题讨论】:

  • sizeof(DataPacket) 仅包含整数成员和指针,没有实际字符串。尝试使用 Qt 序列化,但首先将 char* 替换为 QString。一个成员一个成员的 Qt 序列化就是你所需要的:doc.qt.io/qt-5/qdatastream.html
  • 试试这个: const char * str = dataString.toStdString().c_str(); QByteArray arr= QByteArray::fromRawData(str,sizeof(str));
  • 你解决了我的问题吗?

标签: c++ qt file struct


【解决方案1】:

还有一点是为了保持Qt兼容性重命名一些原生类型,所以我推荐使用等价类型,除了直接使用QString代替char * payload和payloadLength如下图:

struct DataPacket{
    quint32 timestamp;
    quint32 recordType;
    QString payload;
};

另外写的时候最好使用QDataStream,如下图:

QDataStream &operator>>(QDataStream &in, DataPacket &p){
    in >> p.timestamp >> p.recordType >>p.payload;
    return in;
}

QDataStream &operator<<(QDataStream &out, const DataPacket &p){
    out << p.timestamp << p.recordType <<p.payload;
    return out;
}

下面的例子展示了它的用法:

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    const QString fileName = "file.log";

    QString dataString = "$GPGSA,M,3,03,23,22,19,17,01,09,31,12,,,,1.9,0.9,1.6*3D";

    DataPacket pin{1000, 123, dataString};

    QFile fout(fileName);
    if(fout.open(QIODevice::WriteOnly)){
        QDataStream out(&fout);
        out<<pin;
    }
    fout.flush(); // or fout.close();

    DataPacket pout;
    QFile fin(fileName);
    if (fin.open(QIODevice::ReadOnly)) {
        QDataStream in(&fin);
        in>>pout;
        qDebug()<<pout.timestamp<<pout.recordType<<pout.payload;
    }
    return 0;
}

输出:

1000 123 "$GPGSA,M,3,03,23,22,19,17,01,09,31,12,,,,1.9,0.9,1.6*3D"

注意: QDataStream 间接设置payloadLength,因为它知道QString 的大小。

【讨论】:

    【解决方案2】:

    简单得多:

    假设你的结构是“DataPacket”

    void MyClass::write()
    {
    QFile out(FILE_PATH_NAME);
    out.open(QIODevice::WriteOnly);
    out.write((const char *)DataPacket,sizeof(DataPacket));
    out.close();
    }
    
    void MyClass::read()
    {
    QFile in(FILE_PATH_NAME);
    in.open(QIODevice::ReadOnly);
    in.read((const char *)DataPacket,sizeof(DataPacket));
    in.close();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-23
      • 2016-01-26
      • 2013-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-04
      相关资源
      最近更新 更多