2012-09-09 17 views
11

Estoy escribiendo un pequeño programa basado en socket. Estoy usando una clase ModelEvent para pasar información a través del socket. dentro de ModelEvent, hay una variable de tipo de objeto (Object).Java socket/serialization, el objeto no se actualizará

El objeto en sí es una matriz 2D con algunos valores.

object[1][2] = 2; 
ModelEvent event = new ModelEvent("allo", object); 
dispatchEvent(event); 

object[2][3] = 2; 
ModelEvent event2 = new ModelEvent("you", object); 
dispatchEvent(event2); 

Digamos que el objeto de matriz se llena con el valor 1. El primer evento (evento) es recibido por el cliente, y los datos es correcto. El segundo evento enviado aunque los datos no son correctos. Sus datos son los mismos que en el primer envío. el "allo" y "usted" es para ver si no estoy leyendo el mismo evento dos veces y la respuesta no es. La cadena es correcta, pero el objeto no es, evento si se ha actualizado. Paso iterando por la matriz antes de enviar el segundo evento para ver si está actualizado en el servidor, y así es. Pero en el lado del cliente, sigue siendo el mismo que en el primer envío, incluso si el evento en sí se cambia.

+0

¿Cómo lo está leyendo en el lado del cliente? –

+0

ObjectInputStream.readObject y lo lanzo – maniak

Respuesta

20

Ver ObjectOutputStream.reset.

Restablecer hará caso omiso del estado de los objetos ya escritos en la secuencia. El estado se restablece para que sea el mismo que el nuevo ObjectOutputStream. El punto actual en la secuencia se marca como reinicio por lo que el ObjectInputStream correspondiente se reiniciará en el mismo punto. Los objetos previamente escritos en la secuencia no se considerarán como que ya están en la secuencia. Se escribirán en la corriente de nuevo.

/* prevent using back references */ 
output.reset(); 
output.writeObject(...); 

restablecimiento de llamada antes de escribir el mismo objeto para asegurar su estado actualizado es serializado. De lo contrario, simplemente usará una referencia posterior en el objeto previamente escrito con su estado desactualizado.

O, alternativamente, puede usar ObjectOutputStream.writeUnshared de la siguiente manera.

Escribe un objeto "no compartido" en el ObjectOutputStream. Este método es idéntico al writeObject, excepto que siempre escribe el objeto dado como un objeto nuevo y único en la secuencia (a diferencia de una referencia retrospectiva que apunta a una instancia previamente serializada).

Específicamente:

  • Un objeto escrito a través de writeUnshared siempre se serializa en la misma manera que un objeto de nueva aparición (un objeto que no se ha escrito en la corriente todavía), independientemente de si o no la objeto ha sido escrito previamente.

  • Si writeObject se utiliza para escribir un objeto que se haya escrito previamente con writeUnshared, la operación anterior writeUnshared se trata como si fuera una escritura de un objeto separado. En otras palabras, ObjectOutputStream nunca generará referencias retrospectivas a datos de objetos escritos por llamadas al writeUnshared.

Al escribir un objeto a través de writeUnshared no garantiza por sí sola una referencia única para el objeto cuando se deserializa, que permite que un solo objeto a ser definida varias veces en una corriente, de modo que las múltiples llamadas a readUnshared por el receptor no entrará en conflicto.Tenga en cuenta que las reglas descritas anteriormente solo se aplican al objeto de nivel base escrito con writeUnshared, y no a ningún subobjeto referenciado transitoriamente en el gráfico objeto a serializar.

output.writeUnshared(...); 

Nota es una buena práctica a esta pareja con ObjectInputStream.readUnshared.

Lee un objeto "no compartido" del ObjectInputStream. Este método es idéntico a readObject, excepto que evita que las llamadas subsiguientes a readObject y readUnshared devuelvan referencias adicionales a la instancia deserializada obtenida a través de esta llamada.

Específicamente:

  • Si readUnshared se llama deserializar un back-referencia (la representación corriente de un objeto que se ha escrito previamente a la corriente), un ObjectStreamException serán arrojados
  • If readUnshared rendimientos con éxito, cualquier intento subsiguiente de deserializar referencias retrospectivas al identificador de flujo deserializado por readUnshared provocará la emisión de un ObjectStreamException.

Deserializar un objeto a través de readUnshared invalida el identificador de secuencia asociado con el objeto devuelto. Tenga en cuenta que esto en sí mismo no siempre garantiza que la referencia devuelta por readUnshared sea única; el objeto deserializado puede definir un método readResolve que devuelve un objeto visible a otras partes, o readUnshared puede devolver un objeto Class o una constante enum que se puede obtener en cualquier parte de la transmisión o por medios externos. Si el objeto deserializado define un método readResolve y la invocación de ese método devuelve una matriz, entonces readUnshared devuelve una copia superficial de esa matriz; esto garantiza que el objeto de matriz devuelto sea único y no pueda obtenerse por segunda vez a partir de una invocación de readObject o readUnshared en ObjectInputStream, incluso si la secuencia de datos subyacente ha sido manipulada.

obj = input.readUnshared(); 
+1

¡Quiero besarte ahora mismo! * no homo * Gracias. Solo para entender, cuando un objeto se envía dos veces a la transmisión, ¿recuerda su estado anterior y usa el anterior? – maniak

+0

Sí lo hace :)! Creo que es por razones de rendimiento, pero no se adapta al uso que quieres hacer de él. – Flawyte

3

no veo el código dispatchEvent, pero a partir de lo que ha escrito Asumo la siguiente: se escribe el mismo objeto (sólo cambió su estado), esto significa que va a escribir sólo la referencia dos veces . se puede ver en documentos de flujo de salida de Java (para rendimiento).

se debe utilizar writeUnshared(), lo que creará un nuevo objeto en cada escritura

veo se sugirió reinicio, esto le llegar al mismo resultado, pero no tiene impacto en el rendimiento.

+0

+1 para señalar el impacto en el rendimiento. Estaba modificando mi respuesta para incluir 'writeUnshared' mientras publicaba. – oldrinb

+1

-1 para 'impacto en el rendimiento'. La única diferencia entre writeUnshared() y reset()/writeObject() es que, en el primer caso, los objetos referenciados aún se pueden enviar como identificadores.Esa es una gran diferencia * funcional *, y puede que no sea lo que OP quiere en absoluto. Reducir todo eso a un mero "impacto en el rendimiento" es completamente incorrecto y completamente engañoso. – EJP

Cuestiones relacionadas