数据输入流读取的数据与所需的int值不同

时间:2016-03-05 09:03:31

标签: java datainputstream

我正在尝试使用DataInputStream从.dem(反击演示文件)文件中读取。到目前为止,我知道它以标题开头,而在C中它看起来像这样(https://github.com/csgo-data/demoinfogo-linux/blob/master/src/demofile.h

struct demoheader_t
{
    char    demofilestamp[ 8 ];             // Should be HL2DEMO
    int32   demoprotocol;                   // Should be DEMO_PROTOCOL
    int32   networkprotocol;                // Should be PROTOCOL_VERSION
    char    servername[ MAX_OSPATH ];       // Name of server
    char    clientname[ MAX_OSPATH ];       // Name of client who recorded the game
    char    mapname[ MAX_OSPATH ];          // Name of map
    char    gamedirectory[ MAX_OSPATH ];    // Name of game directory (com_gamedir)
    float   playback_time;                  // Time of track
    int32   playback_ticks;                 // # of ticks in track
    int32   playback_frames;                // # of frames in track
    int32   signonlength;                   // length of sigondata in bytes
};

,这是我的标题类,它负责从流中读取它:

package cropper;

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintStream;

import static cropper.Cropper.*;

public class DemoHeader {

    private final static int MAX_OSPATH = 260;
    private final static int STAMP_L = 8;

    char    demofilestamp[];                // Should be HL2DEMO
    int demoprotocol;                   // Should be DEMO_PROTOCOL
    int networkprotocol;                // Should be PROTOCOL_VERSION
    char    servername[];       // Name of server
    char    clientname[];       // Name of client who recorded the game
    char    mapname[];          // Name of map
    char    gamedirectory[];    // Name of game directory (com_gamedir)
    float   playback_time;                  // Time of track
    int   playback_ticks;                   // # of ticks in track
    int   playback_frames;              // # of frames in track
    int signonlength;                   // length of sigondata in bytes

    private DemoHeader(){
        demofilestamp = new char[STAMP_L];
        servername = new char[MAX_OSPATH];
        clientname = new char[MAX_OSPATH];
        mapname = new char[MAX_OSPATH];
        gamedirectory = new char[MAX_OSPATH];
    }

    public static DemoHeader getHeader(DataInputStream dis) throws IOException{
        DemoHeader header = new DemoHeader();
        for (int i = 0; i < header.demofilestamp.length; header.demofilestamp[i++] = (char) dis.readByte());
        header.demoprotocol = dis.readInt();
        header.networkprotocol = dis.readInt();
        for (int i = 0; i < header.servername.length; header.servername[i++] = (char) dis.readByte());
        for (int i = 0; i < header.clientname.length; header.clientname[i++] = (char) dis.readByte());
        for (int i = 0; i < header.mapname.length; header.mapname[i++] = (char) dis.readByte());
        for (int i = 0; i < header.gamedirectory.length; header.gamedirectory[i++] = (char) dis.readByte());
        header.playback_time = dis.readFloat();
        header.playback_ticks = dis.readInt();
        header.playback_frames = dis.readInt();
        header.signonlength = dis.readInt();    
        return header;
    }

    public void println(){
        PrintStream p = System.out;
        p.print("Filestamp - ");
            for (int i = 0; i < 8; p.print(demofilestamp[i++]));
            p.println();
        p.println("Demo protocol - " + Integer.toUnsignedString( demoprotocol ));
        p.println("Network protocol - " + networkprotocol);
        p.print("Server name - ");
            for (int i = 0; i < servername.length; p.print(servername[i++]));
            p.println();
        p.print("Client name - ");
            for (int i = 0; i < clientname.length; p.print(clientname[i++]));
            p.println();
        p.print("Map name - ");
            for (int i = 0; i < mapname.length; p.print(mapname[i++]));
            p.println();
        p.print("Game directory - ");
            for (int i = 0; i < gamedirectory.length; p.print(gamedirectory[i++]));
            p.println();
        p.println("Play back time - " + playback_time);
        p.println("Play back ticks - " + playback_ticks);
        p.println("Play back frames - " + playback_frames);
        p.println("Sign on length - " + signonlength);

    }

}

读取随机.dem文件的标题并将其打印出来

Filestamp - HL2DEMO
Demo protocol - 67108864
Network protocol - -684457984
Server name - eBot :: ENVYUS vs E-Frag.net
Client name - GOTV Demo
Map name - de_cache
Game directory - csgo
Play back time - 1.9518368E-38
Play back ticks - 1084033024
Play back frames - 345769984
Sign on length - -544012032

这对所有数字都是错误的(例如,demoprotocol必须是4)。我做错了什么?

1 个答案:

答案 0 :(得分:1)

我从网上下载了a random .dem file。使用您的代码我得到以下输出:

Filestamp - HL2DEMO
Demo protocol - 67108864
Network protocol - -801898496
Server name - eBot :: mousesports vs E-Frag.net
Client name - GOTV Demo
Map name - de_cache
Game directory - csgo
Play back time - 6.5734844E19
Play back ticks - 595788800
Play back frames - -1451097088
Sign on length - -1433729280

请注意我如何获得与Demo protocol相同的数字。

所以我在十六进制编辑器中打开了文件。这是前12个字节的样子:

48 4C 32 44 45 4D 4F 00 04 00 00 00

前8个字节(48 4C 32 44 45 4D 4F 00)构成字符串HL2DEMO(加上终止空字节\0)。但请注意接下来的4个字节:04 00 00 00。这是整数值4,但在Little Endian中。 Java DataInputStreamint读为Big Endian。

使用Guava的LittleEndianDataInputStream代替Java DataInputStream我得到以下输出:

Filestamp - HL2DEMO
Demo protocol - 4
Network protocol - 13520
Server name - eBot :: mousesports vs E-Frag.net
Client name - GOTV Demo
Map name - de_cache
Game directory - csgo
Play back time - 2310.2734
Play back ticks - 295715
Play back frames - 295593
Sign on length - 494506