Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Alex_C от Март 29, 2012, 18:01



Название: Насколько правильно такое считывание бинарного файла
Отправлено: Alex_C от Март 29, 2012, 18:01
Т.к. перехожу с дельфи, хочу правильно писать программы на Qt.
Хочу чтоб сказали, на сколько правильный код. Нужно считать бинарный фаил, описывающий массив "точек", каждая точка представляет из себя такую структуру:
Код:
struct MapPoint
{
    quint16 code;
    qint16 lat;
    qint16 lon;
};
считываю так
Код:
    QFile f(fileName);
    if(!f.open(QIODevice::ReadOnly))
    {
        QMessageBox::critical(0, "Error!", "Can not open " + fileName);
        return false;
    }

    quint64 poinCount = f.size() / (sizeof(quint16) + sizeof(qint16) * 2);

    mapPoints = new QVector<MapPoint>;
    mapPoints->resize(poinCount);

    QDataStream in(&f);

    int i = 0;
    MapPoint m;
    while (!in.atEnd()) {
        in >> m.code >> m.lat >> m.lon;
        mapPoints->append(m);
        i++;
    }



Название: Re: Насколько правильно такое считывание бинарного файла
Отправлено: Igors от Март 29, 2012, 18:12
Вы не должны делать никаких предположений о длине данных на диске - она может очень отличаться от sizeof. Ну и f.size() вообще не годится если в файле что-то еще

А главное - все проще. Определите операторы << и >> для Вашей структуры (элемента вектора) и спокойно используйте >> для вектора
Код:
QDataStream in(&f);
in >> mapPoints;
И все дела



Название: Re: Насколько правильно такое считывание бинарного файла
Отправлено: m_ax от Март 29, 2012, 18:19
Лучше так:
Код
C++ (Qt)
   QFile file(fileName);
   if(!file.open(QIODevice::ReadOnly)) {
       QMessageBox::critical(0, "Error!", "Can not open " + fileName);
       return false;
   }
 
   QVector<MapPoint> mapPoints;
   QDataStream in(&file);
   in >> mapPoints;
 

Нужно только перегрузить операторы:
Код
C++ (Qt)
QDataStream &operator<<(QDataStream & out, const MapPoint &mp) {
   out << mp.code << mp.lat << mp.lon;
   return out;
}
 
QDataStream &operator>>(QDataStream & in, MapPoint &mp) {
   in >> mp.code >> mp.lat >> mp.lon;  
   return in;
}
 
 


Название: Re: Насколько правильно такое считывание бинарного файла
Отправлено: Blackwanderer от Март 30, 2012, 06:36
И не забывайте про QDataStream::setVersion()


Название: Re: Насколько правильно такое считывание бинарного файла
Отправлено: sidsukana от Март 30, 2012, 06:47
Можно так еще, старт позицию и длину сам укажешь. Длина обычно sizeof() - опять же если ты уверен в том что там именно эти данные.
Код
C++ (Qt)
QByteArray buffer = file.readAll();
MapPoint point = *reinterpret_cast<MapPoint*>(buffer.mid(startpos, length).data());


Название: Re: Насколько правильно такое считывание бинарного файла
Отправлено: Alex_C от Март 30, 2012, 08:53
Всем большое спасибо за ответы!
Вопрос по последнему варианту
Код:
QByteArray buffer = file.readAll();
MapPoint point = *reinterpret_cast<MapPoint*>(buffer.mid(startpos, length).data());

Зачем после mid еще data стоит? mid ведь и так QByteArray возвращает?


Название: Re: Насколько правильно такое считывание бинарного файла
Отправлено: sidsukana от Март 30, 2012, 09:12
А у тебя MapPoint в QByteArray разве?) Приведение типа происходит из сырых данных.


Название: Re: Насколько правильно такое считывание бинарного файла
Отправлено: Igors от Март 30, 2012, 13:41
Можно так еще, старт позицию и длину сам укажешь. Длина обычно sizeof() - опять же если ты уверен в том что там именно эти данные.
Код
C++ (Qt)
QByteArray buffer = file.readAll();
MapPoint point = *reinterpret_cast<MapPoint*>(buffer.mid(startpos, length).data());
Это "как не надо делать" - блочное чтение в стиле C пригодное только для POD структур, да и то не всегда. Суть никак не меняется от того что использованы классы и reinterpret_cast вместо "просто приведения"


Название: Re: Насколько правильно такое считывание бинарного файла
Отправлено: sidsukana от Март 30, 2012, 13:57
Ну, можно директивой выравнивания структур воспользоваться.


Название: Re: Насколько правильно такое считывание бинарного файла
Отправлено: m_ax от Март 30, 2012, 14:09
Ну, можно директивой выравнивания структур воспользоваться.
А можно просто один раз по-человечески сделать и забыть)


Название: Re: Насколько правильно такое считывание бинарного файла
Отправлено: Igors от Март 30, 2012, 14:18
Ну, можно директивой выравнивания структур воспользоваться.
Пользовался :) Вообще в свое время я довольно долго держался за такое запись/чтение, хотя минусы перли из всех щелей. Просто конец всегда один - это придется вычистить. Поэтому если человек начинает - нет смысла ему это рекомендовать.
А можно просто один раз по-человечески сделать и забыть)
За спиной мощного инструментария легко быть смелым  :)


Название: Re: Насколько правильно такое считывание бинарного файла
Отправлено: sidsukana от Март 30, 2012, 14:20
Пользовался :) Вообще в свое время я довольно долго держался за такое запись/чтение, хотя минусы перли из всех щелей. Просто конец всегда один - это придется вычистить. Поэтому если человек начинает - нет смысла ему это рекомендовать.

Ну я сейчас тоже перевожу свои тулзы на стримеры))


Название: Re: Насколько правильно такое считывание бинарного файла
Отправлено: m_ax от Март 30, 2012, 14:31
Цитировать
За спиной мощного инструментария легко быть смелым 
Скорее спокойным за то, что в один прекрасный день, в самый ответственный момент не произойдёт грохинга программы)