This is my first post on here, so apologies for the problems it likely has.
I've been working with a custom input stream recently, that uses a byte array to store data in (similar to a ByteArrayInputStream) but with more control over the pointer. The problem is for some reason my implementation of read() starts returning negative numbers after the values get past 127, which causes DataInputStream to assume it's the EOF.
I've condensed things into a small program to demonstrate the problem:
(broken up into pieces, because I can't seem to figure out how to fit it all into a single code block)
The custom input stream class:
class TestByteArrayInputStream extends InputStream {
byte[] data;
{
// fill with some data
ByteArrayOutputStream out = new ByteArrayOutputStream();
DataOutputStream dout = new DataOutputStream(out);
try {
for (int i = 0; i < 256; i++) { // fill array with shorts valued 0-255
dout.writeShort(i);
}
} catch (Throwable t) {
t.printStackTrace();
}
data = out.toByteArray();
}
int pointer = 0;
@Override
public int read() throws IOException {
if (pointer >= data.length) {
pointer = 0;
}
return data[pointer++]; // I've tried casting this to a char to remove signing, and using Integer.valueOf, but neither solve the problem.
}
}
And here's the main method:
public class Bugdemo {
public static void main(String[] args) {
TestByteArrayInputStream tin = new TestByteArrayInputStream();
DataInputStream din = new DataInputStream(tin);
try { // read through normally
for (int i = 0; i < 256; i++) {
System.out.println(din.readShort());
}
} catch (Throwable t) {
System.out.println(t.toString()); // avoid logging issues
}
tin.pointer = 0; // reset to beginning of data
try {
for (int i = 0; i < 256; i++) {
// readShort code with added debugging
int ch1 = tin.read();
int ch2 = tin.read();
if ((ch1 | ch2) < 0) {
System.out.print("readshort \"eof\": ");
System.out.printf("data in array is %02X ", tin.data[tin.pointer - 2]);
System.out.printf("%02X ", tin.data[tin.pointer - 1]);
System.out.printf(" but got %02X ", ch1);
System.out.printf("%02X from read()", ch2);
System.out.println();
//throw new EOFException(); // this is in DataInputStream.readShort after if((ch1 | ch2) < 0)
} else {
System.out.println((short) ((ch1 << 8) + (ch2 << 0)));
}
}
} catch (Throwable t) {
t.printStackTrace();
}
}
}
And here's the output (pasted so this isn't too long): http://paste.ubuntu.com/6642589/ (is there a better way of doing this on here?)
The important bit:
readshort "eof": data in array is 00 80 but got 00 FFFFFF80 from read()
From my debugging I'm pretty sure it's a casting issue from the byte in the array to an int for returning in read(), but shouldn't it cast properly naturally? If not, what's the proper way of doing this?
readShort
works as expected, read
too.
Integer datatypes in Java are signed, including byte
. As read
returns a byte
and you are outputting this value as it is you get the negative representation. You have to convert it to an int
with the unsigned value before printing with ch1 & 0xff
.