java - objectinputstream e objectoutputstream




Invio dello stesso oggetto ma modificato su ObjectOutputStream (3)

Ho il seguente codice che mostra un bug o un malinteso da parte mia.

Ho inviato la stessa lista, ma modificata su un ObjectOutputStream. Una volta come [0] e altri come [1]. Ma quando lo leggo, ottengo [0] due volte. Penso che questo sia causato dal fatto che sto inviando lo stesso oggetto e ObjectOutputStream deve essere memorizzato nella cache in qualche modo.

Funziona come dovrebbe, o dovrei presentare un bug?

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 stream ha un grafico di riferimento, quindi un oggetto che viene inviato due volte non darà due oggetti sull'altra estremità, ne otterrai solo uno. E inviando lo stesso oggetto due volte separatamente, otterrai la stessa istanza due volte (ognuno con gli stessi dati - che è ciò che stai vedendo).

Vedere il metodo reset () se si desidera ripristinare il grafico.


Quello che probabilmente vuoi è:

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

In caso contrario, lo stesso oggetto verrà svuotato due volte quando il flusso viene chiuso o il buffer si esaurisce.

Solo FYI, quando deserializzi gli oggetti, diciamo o1 e o2 , o1 != o2 .


ObjectOutputStream memorizza ObjectOutputStream cache le istanze che invia sul filo (non necessariamente il miglior design tbh). In ogni caso, è necessario ripristinare i flussi di output tra le chiamate se si prevede di utilizzarlo per (re) inviare la stessa istanza di oggetto.

public void reset() throws IOException

Il ripristino ignorerà lo stato di tutti gli oggetti già scritti nello stream. Lo stato viene reimpostato per essere uguale a un nuovo ObjectOutputStream . Il punto corrente nel flusso viene contrassegnato come ripristinato, quindi il corrispondente ObjectInputStream verrà ripristinato nello stesso punto. Gli oggetti precedentemente scritti nello stream non verranno indicati come già presenti nello stream. Saranno nuovamente scritti nel flusso.





objectoutputstream