目录
Qt关于遇到0x00提前结束的问题
假如有如下一个文件,数据中包含大量的0x00
QFile firmwarefile(filePath);
firmwarefile.open(QIODevice::ReadOnly);
//方法1:全部读取
QByteArray ba = firmwarefile.readAll(); //正确
//方法2:读一行,指定长度
char buf[1024];
qint64 lineLength;
lineLength = firmwarefile.readLine(buf, sizeof(buf)); //正确,此时不要debug看buf里面的数据,因为0x00的存在,在debug中只能看到前两个字节
//方法3:读指定长度到缓冲区
int num = 1024*1;//每次读取固件大小
char *sendBuffer=new char[num]();
lineLength = firmwarefile.read(sendBuffer, num); //正确,此时不要debug看sendBuffer里面的数据,因为0x00的存在,在debug中只能看到前两个字节
delete [] sendBuffer;
firmwarefile.close();
QFileInfo fileInfo = QFileInfo(filePath);
QString fileName = fileInfo.fileName();
std::string str = filePath.toStdString();
FILE *fp;
fopen_s(&fp, str.c_str(), "r");
char *dataBuffer = new char[fileInfo.size()]();
fread(dataBuffer, fileInfo.size(), 1, fp); //正确,此时不要debug看dataBuffer里面的数据,因为0x00的存在,在debug中只能看到前两个字节
delete [] dataBuffer;
fclose(fp);
如果将文件数据读取到了QByteArray中,需要将QByteArray的数据取出时,可以采用如下两种方法
方法1:
QByteArray ba = firmwarefile.readAll();
char *dataBuffer = new char[ba.size()]();
memcpy(dataBuffer, ba.data(), ba.size());
qDebug() << ba.size() = << ba.size();
for (int i = 0; i < ba.size(); i++) {
qDebug() << dataBuffer[i];
}
方法2:
QByteArray ba = firmwarefile.readAll();
char *data = ba.data();
while(*data) //错误,while循环遇到第一个0x00即结束
{
qDebug() << *data;
++data;
}
for (int i = 0; i < ba.size(); i++) { //正确,可完整输出QByteArray中的内容
qDebug() << data[i];
}
假如在生成的probuf中有如下两个重载函数
inline void FirmwareInfo::set_firmwarefile(const char* value) {
GOOGLE_DCHECK(value != nullptr);
firmwarefile_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
// @@protoc_insertion_point(field_set_char:FirmwareInfo.firmwareFile)
}
inline void FirmwareInfo::set_firmwarefile(const void* value, size_t size) {
firmwarefile_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
::std::string(reinterpret_cast(value), size));
// @@protoc_insertion_point(field_set_pointer:FirmwareInfo.firmwareFile)
}
要将含有0x00的char数组放入probuf中时,只能调用第二个重载函数
FirmwareInfo *firmwareInfo=new FirmwareInfo();
firmwareInfo->set_firmwarefile(sendBuffer, length); //其中length为数组的大小
如果调用第一个重载函数,probuf中只能写入0x00以前的数据,0x00之后的数据丢失
QByteArray ba = firmwarefile.readAll();
char *dataBuffer = new char[ba.size()]();
memcpy(dataBuffer, ba.data(), ba.size());
//方法1:指定长度
QByteArray sendData = QByteArray(dataBuffer, ba.size()); //正确
//方法2:
QByteArray sendData = QByteArray(dataBuffer); //错误,sendData中只包含0x00以前的数据
6、socket发送
对于tcp通信,没有特别要求,均可正确写入缓冲区
方法1:
int fd = tcpConnect->write(sendData); //正确
方法2:
int fd = tcpConnect->write(sendData,sendData.length())); //正确
总结:处理含有大量0x00的数据,指定数据长度很重要!