Delphi в Qt / C ++: поток памяти

1

У меня есть код 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)?

Теги:
qt

2 ответа

2
Лучший ответ

На самом деле они оба ошибаются. Проблема заключается в том, что это утверждение. Когда вы читаете целое число, вы должны знать о сути этого файла.

Откройте файл в шестнадцатеричном редакторе и взгляните на целое число, с которым вы столкнулись. Если младший младший байт является первым, это малопринятый. Если самый старший байт - первый, то он большой. (И да, это все ссылки на поездки Гулливера.)

Когда ваш 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();

Разумеется, вы можете ускорить процесс чтения больших фрагментов файла в массив и декодирования из массива, а не байтового байта.

Надеюсь это поможет.

  • 0
    Спасибо, D, это мне очень поможет. Я подумал о написании функции, задающей ей позицию и длину и возвращающей целое число. Я буду использовать бит-сдвиг для достижения желаемого результата.
2

Дутомас прав, говоря о проблемах с эндией. Вы должны знать свой формат файла, чтобы читать его правильно.

Чтобы ответить на другую часть вашего вопроса, вам нужно использовать класс Qt QIOStream для доступа к файлу на более узком уровне. Вы также можете указать QUIStream, который имеет формат endian, и он будет фиксировать числа для вас.

  • 0
    Спасибо, Джон. Я отмечу это для случая, когда я, возможно, произвожу рефакторинг кода после того, как я заставлю его работать с моим первым проходом переписать

Ещё вопросы

Сообщество Overcoder
Наверх
Меню