I have a problem with ByteArrayInputStream + ObjectInputStream (and corresponding output streams).
I want to write some (different) instances of the class Pair over an UDP channel, and I've managed to this way:
For writing (this.scores is a HashMap<String, Integer> and this.completed is an ArrayList<String> (assuming its size() is 2 in this example))
for(String userWhoCompleted : this.completed) {
try(ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);) {
oos.writeUnshared(new Pair<String, Integer>(userWhoCompleted, this.scores.get(userWhoCompleted)));
oos.flush();
this.resultChannel.write(ByteBuffer.wrap(baos.toByteArray()));
} catch(IOException e) { e.printStackTrace(); }
}
For reading (buf is a ByteBuffer)
while(scoresReceived != 2) { // 2 is temporary
buf.clear();
try {
this.multicastChannel.receive(buf);
} catch(IOException e) { e.printStackTrace(); }
try(ByteArrayInputStream bais = new ByteArrayInputStream(buf.array(), 0, buf.position());
ObjectInputStream ois = new ObjectInputStream(bais);) {
Pair<String, Integer> result = (Pair<String, Integer>) ois.readUnshared();
System.out.println(result);
} catch(IOException | ClassNotFoundException e) { e.printStackTrace(); }
}
With this code I can read all the 2 objects written on the channel correctly.
But as you can see, I had to create a new instance of baos, oos, ois and bais on every new loop cycle.
I tried to create those objects outside the loop, and then to do oos.writeUnshared(baos.toByteArray) + baos.reset() and readUnshared respectively on the server and client side but I got StreamCorruptedException: invalid stream header when reading. If I remove baos.reset() I read always the same object, that is the first written to the oos.
What did I do wrong? Is this the only way to work around these problems?
PS: The class Pair is Serializable:
import java.io.Serializable;
public class Pair<F extends Serializable, S extends Serializable> implements Serializable {
private static final long serialVersionUID = 1L;
private F first;
private S second;
public Pair(F first, S second) {
this.first = first;
this.second = second;
}
public F getFirst() { return first; }
public S getSecond() { return second; }
public String toString() {
return "First: " + this.first.toString() + " Second: " + this.second.toString();
}
}