У меня есть код Delphi, который нужно преобразовать в Qt/C++.
Общий код считывает двоичный файл данных и извлекает части данных.
Код Delphi считывает содержимое файла следующим образом:
var
m1 tmemorystream;
h1 integer;
.
.
m1 := tmemorystream.Create;
m1.LoadFromFile(paramstr[1]);
m1.Read (h1, 2);
Теперь, если первые 2 байта в файле "01 00", я ожидал бы, что h1 будет 0x0100, но вместо этого он, кажется, читает "Backwards", поэтому значение в h1 на самом деле "00 01", то есть 0x1.
Эквивалент в Qt я должен прочитать файл:
QFile fileIn(iFile);
if (!fileIn.open(QIODevice::ReadOnly)) return;
QByteArray m1 = fileIn.readAll();
Как читать первые 2 байта в h1 так же, как в коде Delphi? Кажется, что у Delphi есть способ указать количество байтов для чтения из потока /bytearray в целочисленное представление, но это, похоже, отменено.
Эквивалент, который я могу придумать в Qt для достижения такого же результата:
QString tStg;
tStg.sprintf ( "0x%02x%02x", getUChar ( m1, 1), getUChar ( m1, 0) );
bool ok;
unsigned long h1;
h1 = tStg.toLong(&ok,16);
Кажется, длинный ветер и неэлегант... я был новичком в C++.
Поэтому мой вопрос в первую очередь заключается в прямом эквиваленте Delphi tmemeorystream.Read in Qt?
Есть ли лучший способ извлечения диапазона байтов в sinlge long/integer, как в коде Delphi (переменная h1)?
На самом деле они оба ошибаются. Проблема заключается в том, что это утверждение. Когда вы читаете целое число, вы должны знать о сути этого файла.
Откройте файл в шестнадцатеричном редакторе и взгляните на целое число, с которым вы столкнулись. Если младший младший байт является первым, это малопринятый. Если самый старший байт - первый, то он большой. (И да, это все ссылки на поездки Гулливера.)
Когда ваш C++ код читает файл, обязательно узнайте, как его исправить. Лучший способ, на мой взгляд, - всегда читать байты и битово-сдвигать значения в их правильные места:
// little endian
int x = 0;
x = (unsigned char)f.get();
x |= (unsigned char)f.get() << 8;
x |= (unsigned char)f.get() << 16;
x |= (unsigned char)f.get() << 24;
// big endian
int x = 0;
x = (unsigned char)f.get();
x <<= 8; x |= (unsigned char)f.get();
x <<= 8; x |= (unsigned char)f.get();
x <<= 8; x |= (unsigned char)f.get();
Разумеется, вы можете ускорить процесс чтения больших фрагментов файла в массив и декодирования из массива, а не байтового байта.
Надеюсь это поможет.
Дутомас прав, говоря о проблемах с эндией. Вы должны знать свой формат файла, чтобы читать его правильно.
Чтобы ответить на другую часть вашего вопроса, вам нужно использовать класс Qt QIOStream для доступа к файлу на более узком уровне. Вы также можете указать QUIStream, который имеет формат endian, и он будет фиксировать числа для вас.