LINUX.ORG.RU

Как прочитать бинарный файл в qt


0

1

Здравствуйте. Помогите пожалуйста прочитать бинарный файл. Структура его следующая:

UINT8[80] – заголовок
UINT32 – количество треугольников (по сути n)

для каждого треугольника
REAL32[3] – вектор нормали
REAL32[3] – вершина 1
REAL32[3] – вершина 2
REAL32[3] – вершина 3
UINT16 – Attribute byte count
end

Пытался что-то наковырять из интернетов о fstream но ничего не получилось. К тому же у Qt есть такие интересные классы как QFile , но как подгружать бинарные файлы тоже не осилил...

★★★

Не уверен на 100% (тк с Qt на практике не работал). Но подозреваю, что надо смотреть на QByteArray и QBuffer.

DELIRIUM ☆☆☆☆☆
()

Документацию читать пробовал? Тут есть всё это с примерами чтения произвольных файлов.

gentoo_root ★★★★★
()
Ответ на: комментарий от Deleted

вот тут то у меня и возникла проблема... пробую юзать fstream, получаю ошибку «scene3d.cpp:578: error: ‘fstream’ was not declared in this scope» , хотя, как нормальный добропорядочный гражданин в начале файла я прописал #include <fstream>

disee ★★★
() автор топика
Ответ на: комментарий от disee

#include <iostream>

Пардон, но ваш С++ - говно. Либо C, либо ЛИСП, либо ПЕРЛ.

bk_ ★★
()
Ответ на: комментарий от Deleted

не подскажите, а в чем вот так проблема: file.read((int*)n, sizeof(n));

компилятор ругается:

scene3d.cpp:579: error: no matching function for call to ‘std::basic_fstream<char, std::char_traits<char> >::read(int*, long unsigned int)’

disee ★★★
() автор топика

в С/C++ кстати можно сразу завести структуру, которую нужно вычитать, например такую:

#pragma pack(push,0)

struct Triangle
{
    float norm[3];
    float p1[3];
    float p2[3];
    float p3[3];
};

#pragma pack(pop)

и одним движением сразу ее загрузить

vaino
()
Ответ на: комментарий от disee

в том, что функции нужен аргумент типа char *, а не int * ... на плюсах (и иа си тоже) принято делать как-то так:

struct HeaderData {
  int version;
  int entries;
  int firstEntryOffset;
  char textData[10];
  ...  
};

fstream file("myfile", ios::in | ios::binary);
HeaderData header;
file.read((char*)header, sizeof(HeaderData));
invy ★★★★★
()
Ответ на: комментарий от disee

file.read((int*)n, sizeof(n));

Потому, что нужно так: file.read((char*)&n, sizeof(n));

Если я все правильно понял и n - обычное беззнаковое целое.

Deleted
()
Ответ на: комментарий от invy

Плюсую, протупил немного.

Хотя лучше всего такой вот сырой формат не использовать вообще - если продукт кроссплатформенный, обязательно вылезут проблемы с endianess, и придется городить костыли для их решения. Мне видится более рациональным вариант использовать готовые решения для сериализации в бинарный формат (гугловые protocol buffers и тому подобные).

Deleted
()
Ответ на: комментарий от Deleted

Ну ли как и хотел автор с самого начала использовать Qt, там с этим проблем нет(если указывать версию формата). Хотя, если можно без Qt, то лучше без Qt.

frozenix ★★★
()
Ответ на: комментарий от dave

big endian?

все ес-но зависит от задачи, если это просто кэш, например, то заморачиваться на такое не имеет смысла, если это формат документа - то тут вообще лучше взять XML, например

vaino
()
Ответ на: комментарий от invy

На плюсах так делать не принято, ибо принято знать про выравнивание полей структуры, которое тебя в таком случае скоро за зад укусит.

devinull ★★
()
Ответ на: комментарий от vaino

в моем случае я пытаюсь использовать стандрартный самый простой формат для хранения 3d объекта - stl

disee ★★★
() автор топика
Ответ на: комментарий от Deleted

Продукт только под линукс, и он только открывает (нет возможности изменять/сохранять документ). Кстати этот файл формата stl

disee ★★★
() автор топика
Ответ на: комментарий от devinull

Про проблемы такого варианта я скромно умолчал.
Можно ещё про размеры сей структуры на разных архитекторах/компиляторах/стандартах поговорить, вспомнить о big/little endian и т.п.
Так что конечно в таком варианте такая бинарная сериализация - не самое правильное.

invy ★★★★★
()

QDataStream же, в нем переопределяешь операторы потокового ввода вывода для десериализации структуры и радуешься, stream сам заботится о всякой мишуре типа endian

Gorthauer ★★★★★
()
Ответ на: комментарий от disee

'using namespace std' - считается плохим тоном, обычно пишут std::vector, std::cout, etc.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.