ByteArrayInputStream + ObjectInputStream (および対応する出力ストリーム) に問題があります。
Pair
クラスのいくつかの (異なる) インスタンスをUDP チャネル経由で書きたいのですが、この方法で管理しました:
書き込み用 ( this.scores
is a HashMap<String, Integer>
and this.completed
is an ArrayList<String>
(この例では it が 2 であると仮定size()
))
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(); }
}
読み取り用 (buf
は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(); }
}
このコードを使用すると、チャネルに書き込まれた 2 つのオブジェクトをすべて正しく読み取ることができます。
しかし、ご覧のとおり、新しいループ サイクルごとにbaos
、oos
、ois
およびの新しいインスタンスを作成する必要がありました。これらのオブジェクトをループの外に作成してから、サーバー側とクライアント側でそれぞれ+とbais
を実行しようとしました が、読み取り時に取得しました。削除すると、常に同じオブジェクトを読み取ります。これは、最初に に書き込まれます。私は何を間違えましたか?これがこれらの問題を回避する唯一の方法ですか?oos.writeUnshared(baos.toByteArray)
baos.reset()
readUnshared
StreamCorruptedException: invalid stream header
baos.reset()
oos
PS: クラスPair
は次の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();
}
}