PacketInputStream不向前移动字节

时间:2015-10-02 17:08:52

标签: java byte bytearray inputstream

我有一个这样的PacketInputStream类:

celcius = (fahrint - 32) * (5M / 9);
//5 is of type Decimal now

我正在运行此代码:

public class PacketInputStream extends DataInputStream {

    private static final Charset UTF8 = Charset.forName("UTF-8");

    public PacketInputStream(InputStream myis) {
        super(myis);
    }

    public String readString() throws IOException {
        int length = readVarInt();
        byte[] data = new byte[length];
        readFully(data);
        return new String(data, UTF8);
    }

    public int readVarInt() throws IOException {
        int i = 0;
        int j = 0;
        while (true) {
            int k = read();
            if (k == -1)
                throw new IOException("End of stream");

            i |= (k & 0x7F) << j++ * 7;

            if (j > 5)
                throw new IOException("VarInt too big");

            if ((k & 0x80) != 128)
                break;
        }

        return i;
    }

    public long readVarLong() throws IOException {
        long varInt = 0;
        for (int i = 0; i < 10; i++) {
            byte b = readByte();
            varInt |= ((long) (b & (i != 9 ? 0x7F : 0x01))) << (i * 7);

            if (i == 9 && (((b & 0x80) == 0x80) || ((b & 0x7E) != 0)))
                throw new IOException("VarInt too big");
            if ((b & 0x80) != 0x80)
                break;
        }

        return varInt;
    }

    public byte[] readBytes() throws IOException {
        return readBytes(readShort());
    }

    public byte[] readBytes(int length) throws IOException {
        if (length < 0)
            throw new IOException("Invalid array length");
        byte[] data = new byte[length];
        readFully(data);
        return data;
    }

}

System.out.println("Logic data version (always 0) : " + is.readVarInt()); System.out.println("User ID: " + is.readVarLong()); System.out.println("Home ID: " + is.readVarLong()); 已定义

现在我遇到的问题是它总是显示0作为返回的数字。

这是输入流的第一位: is现在您可以看到它不应该每次为前3个赋予0,那么错误在哪里以及如何解决?

谢谢:)

1 个答案:

答案 0 :(得分:0)

您的输入方式不是根据代码,或者代码不是根据输入。以下是我可以执行代码的方法:

main()的

public static void main(String[] args) throws Exception {
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    byteArrayOutputStream.write(new byte[] { 0, 3,
            4, 5, (byte)128, 0, 0, 3, 0, 0, 3, 5, 0XC, 7, 0, (byte)8, 0, 0, 0, 0, 0, 0,
            0, 3, 0, 0, 3, 5, 0XC, 7, 0, 8, 0, 1, 0, 0, 0, 0, 0, 0, 4 });
    ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(
            byteArrayOutputStream.toByteArray());
    PacketInputStream is = new PacketInputStream(byteArrayInputStream);
    System.out
            .println("Logic data version (always 0) : " + is.readVarInt());
    System.out.println("User ID: " + is.readVarLong());
    System.out.println("Home ID: " + is.readVarLong());
}

需要研究的更多内容:

  1. 为什么i |= (k & 0x7F) << j++ * 7;?为什么不i |= (k & 0xFF) << j++ * 7;
  2. 为什么int k = read();' and not字节k = readByte();`?是varinteger尺寸&gt; varlong size你在哪里读取字节?
  3. 为什么if ((k & 0x80) != 128)而不是if ((k & 0x80) == 128)?我相信if ((k & 0x80) != 128)是您期望终止读取整数的条件。
  4. if ((b & 0x80) != 0x80)应该if ((b & 0x80) == 0x80)吗?
  5. 下面是我尝试读取varint的修改后的类,后面跟着我输入的两个varlong:

        class PacketInputStream extends DataInputStream {
    
            private static final Charset UTF8 = Charset.forName("UTF-8");
    
            public PacketInputStream(InputStream myis) {
                super(myis);
            }
    
            public String readString() throws IOException {
                int length = readVarInt();
                byte[] data = new byte[length];
                readFully(data);
                return new String(data, UTF8);
            }
    
            public int readVarInt() throws IOException {
                int i = 0;
                int j = 0;
                while (true) {
                    byte k = readByte();
                    if (k == -1)
                        throw new IOException("End of stream");
    
                    i |= (k & 0xFF) << j++ * 7;
    
                    if (j > 5)
                        throw new IOException("VarInt too big");
    
                    if ((k & 0x80) == 128)
                        break;
                }
    
                return i;
            }
    
            public long readVarLong() throws IOException {
                long varInt = 0;
                for (int i = 0; i < 10; i++) {
                    byte b = readByte();
                    varInt |= ((long) (b & (i != 9 ? 0x7F : 0x01))) << (i * 7);
    
                    if (i == 9 && (((b & 0x80) == 0x80) || ((b & 0x7E) != 0)))
                        throw new IOException("VarInt too big");
                    if ((b & 0x80) == 0x80)
                        break;
                }
    
                return varInt;
            }
    
            public byte[] readBytes() throws IOException {
                return readBytes(readShort());
            }
    
            public byte[] readBytes(int length) throws IOException {
                if (length < 0)
                    throw new IOException("Invalid array length");
                byte[] data = new byte[length];
                readFully(data);
                return data;
            }
    
        }