PacketInputStream 不向前移动字节
PacketInputStream not moving ahead bytes
我有一个这样的 PacketInputStream class:
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());
is
定义
现在我遇到的问题是它总是显示 0 作为返回数字。
这是输入流的第一位:
00000000000000030035C708000000030035C708010000004
现在您可以看到,前 3 个不应该每次都给出 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());
}
更多要研究的项目:
- 为什么
i |= (k & 0x7F) << j++ * 7;
?为什么不 i |= (k & 0xFF) << j++ * 7;
- 为什么
int k = read();' and not
byte k = readByte();`? varinteger size > varlong size 是按字节读取的吗?
- 为什么
if ((k & 0x80) != 128)
而不是 if ((k & 0x80) == 128)
?我相信if ((k & 0x80) != 128)
是你期待终止读取整数的条件。
if ((b & 0x80) != 0x80)
应该是 if ((b & 0x80) == 0x80)
吗?
下面是修改后的 class,我尝试读取 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;
}
}
我有一个这样的 PacketInputStream class:
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());
is
定义
现在我遇到的问题是它总是显示 0 作为返回数字。
这是输入流的第一位:
00000000000000030035C708000000030035C708010000004
现在您可以看到,前 3 个不应该每次都给出 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());
}
更多要研究的项目:
- 为什么
i |= (k & 0x7F) << j++ * 7;
?为什么不i |= (k & 0xFF) << j++ * 7;
- 为什么
int k = read();' and not
byte k = readByte();`? varinteger size > varlong size 是按字节读取的吗? - 为什么
if ((k & 0x80) != 128)
而不是if ((k & 0x80) == 128)
?我相信if ((k & 0x80) != 128)
是你期待终止读取整数的条件。 if ((b & 0x80) != 0x80)
应该是if ((b & 0x80) == 0x80)
吗?
下面是修改后的 class,我尝试读取 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;
}
}