So you can compare the alternative formats I have written a template which allows you to use any format your wish, or compare the alternatives.
abstract class DataSocket implements Closeable {
private final Socket socket;
protected final DataOutputStream out;
protected final DataInputStream in;
DataSocket(Socket socket) throws IOException {
this.socket = socket;
out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
}
public void writeInts(int[] ints) throws IOException {
writeInt(ints.length);
for (int i : ints)
writeInt(i);
endOfBlock();
}
protected abstract void writeInt(int i) throws IOException;
protected abstract void endOfBlock() throws IOException;
public int[] readInts() throws IOException {
nextBlock();
int len = readInt();
int[] ret = new int[len];
for (int i = 0; i < len; i++)
ret[i] = readInt();
return ret;
}
protected abstract void nextBlock() throws IOException;
protected abstract int readInt() throws IOException;
public void close() throws IOException {
out.close();
in.close();
socket.close();
}
}
binary format, 4-byte ints
class BinaryDataSocket extends DataSocket {
BinaryDataSocket(Socket socket) throws IOException {
super(socket);
}
@Override
protected void writeInt(int i) throws IOException {
out.writeInt(i);
}
@Override
protected void endOfBlock() throws IOException {
out.flush();
}
@Override
protected void nextBlock() {
// nothing
}
@Override
protected int readInt() throws IOException {
return in.readInt();
}
}
stop bit encoded binary with one byte per 7 bits.
class CompactBinaryDataSocket extends DataSocket {
CompactBinaryDataSocket(Socket socket) throws IOException {
super(socket);
}
@Override
protected void writeInt(int i) throws IOException {
// uses one byte per 7 bit set.
long l = i & 0xFFFFFFFFL;
while (l >= 0x80) {
out.write((int) (l | 0x80));
l >>>= 7;
}
out.write((int) l);
}
@Override
protected void endOfBlock() throws IOException {
out.flush();
}
@Override
protected void nextBlock() {
// nothing
}
@Override
protected int readInt() throws IOException {
long l = 0;
int b, count = 0;
while ((b = in.read()) >= 0x80) {
l |= (b & 0x7f) << 7 * count++;
}
if (b < 0) throw new EOFException();
l |= b << 7 * count;
return (int) l;
}
}
text encoded with a new line at the end.
class TextDataSocket extends DataSocket {
TextDataSocket(Socket socket) throws IOException {
super(socket);
}
private boolean outBlock = false;
@Override
protected void writeInt(int i) throws IOException {
if (outBlock) out.write(' ');
out.write(Integer.toString(i).getBytes());
outBlock = true;
}
@Override
protected void endOfBlock() throws IOException {
out.write('\n');
out.flush();
outBlock = false;
}
private Scanner inLine = null;
@Override
protected void nextBlock() throws IOException {
inLine = new Scanner(in.readLine());
}
@Override
protected int readInt() throws IOException {
return inLine.nextInt();
}
}