Программа Qt/C++ имеет функцию, которая записывает данные объектов (_token
) в файл следующим образом:
QFile f( _tokenFile);
if (!f.open( QIODevice::WriteOnly)) {
qDebug() << "Unable to open token file for writing" << f.errorString();
return false;
}
QByteArray tokenBa;
QDataStream ds( &tokenBa, QIODevice::WriteOnly);
ds << _token;
tokenBa = qCompress( tokenBa);
f.write( tokenBa);
f.close();
_token является экземпляром следующих struct
:
struct Token {
QString accessToken;
QString refreshToken;
QString clientSecret;
QString authCode;
QTime expiryTime;
enum AuthState {
A_Invalid,
A_RequestAuth,
A_Authenticated,
};
AuthState state;
Token() : state( A_Invalid) {}
bool isValid() const {
if (accessToken.isEmpty() ||
refreshToken.isEmpty()) {
return false;
}
return true;
}
void inValidate() {
accessToken.clear();
refreshToken.clear();
clientSecret.clear();
authCode.clear();
expiryTime = QTime();
}
void cleanUp() {
accessToken.clear();
refreshToken.clear();
clientSecret.clear();
authCode.clear();
expiryTime = QTime();
}
};
Когда файл сохраняется, в начале у него есть 4 дополнительных байта, которые отображают файл как недопустимый файл zlib.
0000000 0000 5e01 9c78 904d 4f5d 5082 871c fa9f
0000020 353e 25cd 6975 2c2f d563 4c2c 62b8 cad1
Мы видим, что байты 5-6 выше — это 9C 78
, что является сигнатурой zlib, но 4 байта перед ними — это проблема.
Чтобы проверить правильность сжатых данных, я делаю следующее:
dd if=file.token bs=1 skip=4 | openssl zlib -d
И это дает ожидаемый результат (для тестирования).
Проблема заключается в том, что приложение считывает эти данные обратно в объект данных:
QFile f( _tokenFile);
if (!f.exists()) {
qDebug() << "Token file doesn't exist" << f.fileName();
return false;
}
if (!f.open( QIODevice::ReadOnly)) {
qDebug() << "Unable to open token file for reading" << f.errorString();
return false;
}
QByteArray tokenBa = f.readAll();
f.close();
if (tokenBa.isEmpty()) {
qDebug() << "Token file is empty.";
return false;
}
tokenBa = qUncompress( tokenBa);
QDataStream ds( &tokenBa, QIODevice::ReadOnly);
ds >> _token;
Это возвращает null - из-за первых 4 посторонних байтов. Я мог бы добавить некоторый код, чтобы пропустить эти 4 начальных байта, но откуда мне знать, что это всегда будет 4 байта? Вместо этого я хотел бы, чтобы все данные файлов были сжаты zlib.
Мой вопрос заключается в том, как избежать сохранения этих байтов в первую очередь, чтобы при повторном чтении формат был известен как тип zlib?