2013-07-30 4 views
0

мне нужно прочитать двоичный файл, который содержит эту структуру:Java чтение бинарной-структуры

struct iqmheader 
{ 
    char magic[16]; // the string "INTERQUAKEMODEL\0", 0 terminated 
    uint version; // must be version 2 
    uint filesize; 
    uint flags; 
    uint num_text, ofs_text; 
    uint num_meshes, ofs_meshes; 
    uint num_vertexarrays, num_vertexes, ofs_vertexarrays; 
    uint num_triangles, ofs_triangles, ofs_adjacency; 
    uint num_joints, ofs_joints; 
    uint num_poses, ofs_poses; 
    uint num_anims, ofs_anims; 
    uint num_frames, num_framechannels, ofs_frames, ofs_bounds; 
    uint num_comment, ofs_comment; 
    uint num_extensions, ofs_extensions; 
}; 

Есть элегантный способ сделать это? Я попытался javolution LIB таким образом:

import javolution.io.Struct; 
import java.nio.ByteOrder; 

public class IqmHeader extends Struct { 
    public final UTF8String magic = new UTF8String(16); 
    public final Unsigned8 version = new Unsigned8(); 
    public final Unsigned8 filesize = new Unsigned8(); 
} 

Первые 2 значения (магические и версии) являются правильными, но за третий один i'm уже получает 0, который является неправильным.

Файл открыт с Hex Editor (первый байт, а не весь файл):

Вот выход из шестнадцатеричного редактора:

49 4E 54 45 52 51 55 41 4B 45 4D 4F 44 45 4C 00 02 00 00 00 10 EF 03 00 00 00 00 00 60 03 00 00 7C 00 00 00 02 00 00 00 DC 03 00 00 06 00 00 00 45 07 00 00 0C 04 00 00 AC 0B 00 00 A0 9B 01 00 B0 27 02 00 4B 00 00 00 C0 B3 02 00 4B 00 00 00 D0 C1 02 00 01 00 00 00 98 DB 02 00 65 00 00 00 4D 01 00 00 AC DB 02 00 70 E2 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 42 6F 64 

Я должен признать, что я действительно не знаю, как читать это. Первые 16 байтов - это строка, за которой следует «00». Тогда версия «02» - здесь я не знаю, сколько байтов занимает uint

Любые предложения?

+0

Можете ли вы открыть файл в шестнадцатеричном редакторе и убедиться, что размер файла установлен в ненулевое значение в файле? – hexafraction

+0

Alex: Пожалуйста, отредактируйте свой оригинальный пост. – hexafraction

+1

Не знакомы с Javolution, но уверены ли вы, что Unsigned8 является правильным типом для использования в вашем определении? Я предполагаю, что C int будет соответствовать Unsigned32 (предполагая, что такой класс существует в Javolution). –

ответ

0

Используйте DataInputStream и readUnsignedByte, readUnsignedShort, readUTF и т. Д., Чтобы создать структуру.

Вы можете использовать класс Java для представления структуры:

public class IQMHeader { 
    String magic; // the string "INTERQUAKEMODEL\0", 0 terminated 
    long version; // must be version 2 
    long filesize; 
    long flags; 
    long num_text, ofs_text; 
    long num_meshes, ofs_meshes; 
    long num_vertexarrays, num_vertexes, ofs_vertexarrays; 
    long num_triangles, ofs_triangles, ofs_adjacency; 
    long num_joints, ofs_joints; 
    long num_poses, ofs_poses; 
    long num_anims, ofs_anims; 
    long num_frames, num_framechannels, ofs_frames, ofs_bounds; 
    long num_comment, ofs_comment; 
    long num_extensions, ofs_extensions; 
}; 

Вы можете прочитать беззнаковое INT так:

long unsigned = input.readInt() & 0xffffffffL; 
+0

Хм, похоже, не работает: fis = new FileInputStream ("c: \\ temp \\ mrfixit.iqm"); DataInputStream dis = new DataInputStream (fis); System.out.println (dis.readUTF()); -> java.io.UTFDataFormatException: неправильный ввод вокруг байта 21 –

+1

Я забыл сказать, что данные хранятся немного endian. Я думаю, что DataInputStream большой эндиан –

0

Как прокомментировал, вы можете попробовать использовать Unsigned32 представлять версию и другие C int в вашем Java-классе вместо Unsigned8, так как C int должен быть 4 байта, а Unsigned8 представляет только 1 байт.