java - serializar - Enviar el mismo objeto pero modificado sobre ObjectOutputStream
serialización de objetos en java (4)
Tengo el siguiente código que muestra un error o un malentendido de mi parte.
Envié la misma lista, pero modificada sobre ObjectOutputStream. Una vez como [0] y otra como [1]. Pero cuando lo leo, obtengo [0] dos veces. Creo que esto se debe al hecho de que estoy enviando el mismo objeto y ObjectOutputStream debe almacenarlos en caché de alguna manera.
¿Es este trabajo como debería, o debería presentar un error?
import java.io.*; import java.net.*; import java.util.*; public class OOS { public static void main(String[] args) throws Exception { Thread t1 = new Thread(new Runnable() { public void run() { try { ServerSocket ss = new ServerSocket(12344); Socket s= ss.accept(); ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream()); List same = new ArrayList(); same.add(0); oos.writeObject(same); same.clear(); same.add(1); oos.writeObject(same); } catch(Exception e) { e.printStackTrace(); } } }); t1.start(); Socket s = new Socket("localhost", 12344); ObjectInputStream ois = new ObjectInputStream(s.getInputStream()); // outputs [0] as expected System.out.println(ois.readObject()); // outputs [0], but expected [1] System.out.println(ois.readObject()); System.exit(0); } }
Lo que probablemente quieras es:
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
List same = new ArrayList();
same.add(0);
oos.writeObject(same);
oos.flush(); // flush the stream here
same.clear();
same.add(1);
oos.writeObject(same);
De lo contrario, el mismo objeto se descargará dos veces cuando la transmisión se cierre o se agote el almacenamiento intermedio.
Solo FYI, cuando deserializas los objetos, digamos o1
y o2
, o1 != o2
.
La secuencia tiene un gráfico de referencia, por lo que un objeto que se envía dos veces no dará dos objetos en el otro extremo, solo obtendrá uno. Y enviar el mismo objeto dos veces por separado le dará la misma instancia dos veces (cada una con la misma información, que es lo que está viendo).
Vea el método reset () si desea reiniciar el gráfico.
Max es correcto, pero también puedes usar:
public void writeUnshared(Object obj);
Ver comentario a continuación para advertencia
ObjectOutputStream
almacena en caché las instancias que envía a través del cable (no necesariamente el mejor diseño tbh). Pero en cualquier caso, debe restablecer las secuencias de salida entre llamadas si planea usarla para (re) enviar la misma instancia de objeto.
public void reset() throws IOException
Restablecer ignorará el estado de cualquier objeto ya escrito en la secuencia. El estado se restablece para que sea el mismo que un nuevo ObjectOutputStream
. El punto actual en la secuencia se marca como restablecer para que el ObjectInputStream
correspondiente se reinicie en el mismo punto. Los objetos previamente escritos en la secuencia no se mencionarán como que ya están en la secuencia. Se escribirán en la corriente de nuevo.