Russian Qt Forum
Сентябрь 30, 2024, 18:24 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Запись в бинарник.  (Прочитано 6571 раз)
Primordial
Гость
« : Апрель 19, 2012, 15:20 »

Приветствую. С Qt общаюсь пару дней только. Возник вопрос. Есть необходимость скинуть данные в бинарный файл. В общих чертах структура файла должна быть такова: хидер - пакет_0 - пакет_1 - ... - пакет_n. Т.е. сначала должны быть сформированы в памяти нужные пакеты данных, потом заголовок (на основании наличия\отсутствия пакета, его размера и пр.) и лишь в конце все должно быть записано в файл. Вопрос, собственно,  как это реализовать средствами Qt?
Как я понимаю,  класс QDataSrteam приспособлен для ввода данных в QIODevice вообще и, например, в QBuffer, в частности. Как записать данные в буфер, а из него в файл? Например в C# это легко решается с помощью BinaryWriter\MemoryStream. Надо что-то похожее.
Записан
Странник
Гость
« Ответ #1 : Апрель 19, 2012, 15:29 »

ну так и пишите в QByteArray, а потом записывайте QFile. если вам в самом деле необходимо сформировать файл в памяти.
или пишите сразу на диск: пустой заголовок, пакеты, а потом возвращаетесь и перезаписываете заголовок.
Записан
_OLEGator_
Гость
« Ответ #2 : Апрель 19, 2012, 15:34 »

Так напрямую и здесь решается.
Код
C++ (Qt)
QDataStream::QDataStream ( QIODevice * d )
QFile унаследован от QIODevice.
Записан
Primordial
Гость
« Ответ #3 : Апрель 20, 2012, 23:26 »

Благодарю, в общем разобрался немного.
Цитировать
или пишите сразу на диск: пустой заголовок, пакеты, а потом возвращаетесь и перезаписываете заголовок.
Не, так не стоит. Вдруг я решу сделать хидер не фиксированного размера. Да и некрасиво как-то.
Но остался еще такой момент. Я до недавнего времени на Delphi в основном писал, так что некоторые особенности C++ мне очень непривычны.
В общих чертах последовательность моих действий такова:
Код:
void ProcessData()
{
    /* Try to open dest file... */
    QFile myFile(destFileName);
    if ( !myFile.open(QIODevice::WriteOnly) )
        ThrowException(etFailedToOpenOutputFile, "Failed to open output file!");
   
    /*  Try to process data. Fill buffers here...  */
    //   ...
    //   ...
    //   ...
   
    /*  Finalizing...  */
    FlushProcessedData();
    myFile.close();

}
Во фрагменте кода в середине (обработка данных, заливка данных в буферы) может произойти исключение (я сам его возбуждаю), таким образом до фрагмента кода помеченного как "Finalizing..." выполнение не дойдет, следовательно, не будет вызван myFile.close(); Насколько это критично? Как я понимаю, в случае исключения выполнение функции остановиться и объект myFile будет подчищен и файл будет закрыт. Или я ошибаюсь?
Записан
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


Просмотр профиля
« Ответ #4 : Апрель 20, 2012, 23:32 »

При раскрутке стека по исключению, QFile в деструкторе зовет close(), так что не стоит волноваться. Также почитайте о RAII, этот подход полезно использовать при работе с исключениям. Да и вообще удобно.

Я знаю как ломает, когда с Дельфи приходишь а в плюсцах нету try/finally Веселый
Записан

Гугль в помощь
Primordial
Гость
« Ответ #5 : Апрель 20, 2012, 23:44 »

Ну я так и полагал, но решил уточнить на всякий случай Улыбающийся
И еще по теме. У меня в классе экспортера имеется ряд буферов типа
Код:
    QBuffer buf_Packet_0;
    QBuffer buf_Packet_1;
    QBuffer buf_Packet_2;
    ....
куда, собственно, и пишутся данные перед тем как они будут записаны в выходной файл. Пишутся данные посредством QDataStream. По идее, надо бы очистить эти буферы на случай повторного вызова функции экспорта (буферы-то не локальные объекты). На данный момент я пишу вот так:
Код:
    buf_Packet_0.buffer().resize(0);
    buf_Packet_1.buffer().resize(0);
    buf_Packet_2.buffer().resize(0);
    ...
Это то что мне надо или нет?
Записан
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


Просмотр профиля
« Ответ #6 : Апрель 20, 2012, 23:51 »

Ну по поводу надо или нет ничего не скажу, но очистка такая вроде должна прокатить. Также можно очистить следующими способами:
Код
C++ (Qt)
buf_Packet_0 = QBuffer();
buf_Packet_0.setBuffer(QByteArray());

и определись с codestyle: bufPacket0 или buf_packet_0...
Записан

Гугль в помощь
Primordial
Гость
« Ответ #7 : Апрель 21, 2012, 22:37 »

Походу проще все : void QByteArray::clear (). Что-то я с первого взгляда не обнаружил этой ф-ции, удивился даже.
Еще один вопрос. Допустим есть код типа такого:
Код:
void DoSomething()
{
    ...
    QList<QBuffer*> bufferList;
   
    for ( int i = 0; i < n; i++ )
    {
         QBuffer tmpBuffer;
         //  do something here
         bufferList.push_back(&tmpBuffer);
    }

    /*  Buffer list processing here...      */
    ...
}
У меня возникают сомнения по поводу правильности такого кода. В цикле в экземпляр QList вносится указатель на объект типа QBuffer. Но я пока не до конца понимаю тонкостей времени жизни объектов. После выхода из цикла эти объекты (QBuffer) еще существуют? К ним будет доступ после цикла?
Записан
V1KT0P
Гость
« Ответ #8 : Апрель 21, 2012, 22:45 »

Походу проще все : void QByteArray::clear (). Что-то я с первого взгляда не обнаружил этой ф-ции, удивился даже.
Еще один вопрос. Допустим есть код типа такого:
Код:
void DoSomething()
{
    ...
    QList<QBuffer*> bufferList;
   
    for ( int i = 0; i < n; i++ )
    {
         QBuffer tmpBuffer;
         //  do something here
         bufferList.push_back(&tmpBuffer);
    }

    /*  Buffer list processing here...      */
    ...
}
У меня возникают сомнения по поводу правильности такого кода. В цикле в экземпляр QList вносится указатель на объект типа QBuffer. Но я пока не до конца понимаю тонкостей времени жизни объектов. После выхода из цикла эти объекты (QBuffer) еще существуют? К ним будет доступ после цикла?
Нет конечно, все что объявлено между фигурными скобками дохнет после выхода из них.
Записан
Primordial
Гость
« Ответ #9 : Апрель 22, 2012, 21:05 »

А такой вопрос. Есть ли в Qt\Qt Creator инструменты для отслеживания утечек памяти?
Записан
V1KT0P
Гость
« Ответ #10 : Апрель 22, 2012, 21:09 »

А такой вопрос. Есть ли в Qt\Qt Creator инструменты для отслеживания утечек памяти?
Под линуксом можешь Valgrind подключить.
Записан
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


Просмотр профиля
« Ответ #11 : Апрель 22, 2012, 23:09 »

+1

Под линуксом valgrind отлично интегрирован в Qt Creator (профайлер и memcheck). Под виндой остается только юзать платные тулзы (AQTime, DevPartner).

Вообще под плюсы лучше разработку вести в линуксе (быстрее и удобнее).
Записан

Гугль в помощь
Primordial
Гость
« Ответ #12 : Апрель 22, 2012, 23:19 »

Я пока WinXP для работы использую. На вирт. машине установлен Debian, который планирую использовать в качестве локального web-сервера, когда руки дойдут. Хотел Ubuntu поставить, но, к сожалению, дистр. не встал на вирт. машину. А какие ключевые особенности и плюсы разработки под c++ в линуксе?
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.158 секунд. Запросов: 23.