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();
}
}