see - javadoc exemple




Que se passe-t-il lorsque j'entoure des flux d'E/S deux fois? (2)

Je sais que Java I / O utilise un motif de décorateur. Mais je sens que je comprends mal.

Veuillez clarifier la différence entre deux extraits de code:

extrait 1:

    PipedInputStream pipedInputStream = new PipedInputStream();
    PipedOutputStream pipedOutputStream = new PipedOutputStream();
    pipedOutputStream.connect(pipedInputStream);


    ObjectOutputStream objectOutputStream = new ObjectOutputStream(pipedOutputStream);

    objectOutputStream.writeObject("this is my string");

    ObjectInputStream objectInputStream = new ObjectInputStream(pipedInputStream);

    System.out.println(objectInputStream.readObject());

Cette application fonctionne selon mes attentes et je vois le résultat dans la console.

extrait 2:

J'essaie d'encapsuler ObjectInputStream et ObjectOutputStream deux fois:

        PipedInputStream pipedInputStream = new PipedInputStream();
        PipedOutputStream pipedOutputStream = new PipedOutputStream();
        pipedOutputStream.connect(pipedInputStream);


        ObjectOutputStream objectOutputStream = new ObjectOutputStream(pipedOutputStream);
        ObjectOutputStream objectOutputStreamWrapper = new ObjectOutputStream(objectOutputStream);     //double wrapping

        objectOutputStreamWrapper.writeObject("this is my string");

        ObjectInputStream objectInputStream = new ObjectInputStream(pipedInputStream);
        ObjectInputStream   objectInputStreamWrapper = new ObjectInputStream(objectInputStream);

        System.out.println(objectInputStreamWrapper.readObject());

Ce code raccroche simplement. Je ne comprends pas pourquoi. précisez s'il vous plaît.

PS

C'est une question théorique seulement.

METTRE À JOUR

Vraiment raccroche le comportement se produit en raison de l'utilisation de tuyaux (selon la réponse EJP).

par exemple ce code fonctionne selon les attentes.

            OutputStream outputStream = new FileOutputStream("2.txt");

            ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
            ObjectOutputStream objectOutputStreamWrapper = new ObjectOutputStream(objectOutputStream);     //double wrapping

            objectOutputStreamWrapper.writeObject("this is my string");
            objectOutputStream.close();

            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("2.txt"));
            ObjectInputStream   objectInputStreamWrapper = new ObjectInputStream(objectInputStream);


            System.out.println(objectInputStreamWrapper.readObject());
            objectInputStream.close();

On dirait que si j'emballe la contribution de 10 décorateurs, je devrais emballer la sortie par 10 décorateurs dans le même ordre. Est-ce vrai ?

MISE À JOUR + 1

J'ai remarqué ce problème avec le rinçage seulement:

PipedInputStream pipedInputStream = new PipedInputStream();
    PipedOutputStream pipedOutputStream = new PipedOutputStream();
    pipedOutputStream.connect(pipedInputStream);


    ObjectOutputStream objectOutputStream = new ObjectOutputStream(pipedOutputStream);
    ObjectOutputStream objectOutputStreamWrapper = new ObjectOutputStream(objectOutputStream);     //double wrapping

    objectOutputStreamWrapper.writeObject("this is my string");

    objectOutputStreamWrapper.flush();

    ObjectInputStream objectInputStream = new ObjectInputStream(pipedInputStream);
    ObjectInputStream   objectInputStreamWrapper = new ObjectInputStream(objectInputStream);

    System.out.println(objectInputStreamWrapper.readObject());

Vous utilisez abusivement les cours d'eau. Ils sont destinés à être utilisés par un thread producteur effectuant des écritures et un thread consommateur effectuant des lectures. Voir le Javadoc.

Les flux canalisés partagent un tampon qui peut se remplir si le thread de lecture ne lit pas, ce qui bloque votre fil d'écriture.

Envelopper les flux deux fois n'a rien à voir avec cela, même si dans ce cas, il est certainement à la fois inutile et problématique.


PipedInputStream pipedInputStream = new PipedInputStream();
PipedOutputStream pipedOutputStream = new PipedOutputStream();
pipedOutputStream.connect(pipedInputStream);
//writing 
ObjectOutputStream objectOutputStream = new ObjectOutputStream(pipedOutputStream);
//ObjectOutputStream objectOutputStreamWrapper =new ObjectOutputStream(objectOutputStream);
//ObjectOutputStream objectOutputStreamWrapper1=new ObjectOutputStream(objectOutputStreamWrapper);
//objectOutputStreamWrapper1.writeObject("this is my string");
//objectOutputStreamWrapper1.flush();
objectOutputStream.writeObject("this is my string");
//reading 
ObjectInputStream objectInputStream = new ObjectInputStream(pipedInputStream);
//ObjectInputStream objectInputStreamWrapper = new ObjectInputStream(objectInputStream);
//ObjectInputStream objectInputStreamWrapper1=new ObjectInputStream(objectInputStreamWrapper);
//System.out.println("going to read from piped source");
//System.out.println(objectInputStreamWrapper1.readObject());
System.out.println(objectInputStream.readObject());

Snippet 1 - OutputStream créé avec un flux Piped, puis le flux d'entrée reçoit directement les données du tube via le buffer sans vidage.

Update + 1 - OutputStream créé avec wrapper outputtream à son tour avec un autre wrapper (a commenté les déclarations wrapper) et ainsi de suite fonctionne après la déclaration de flush. Vider explicitlty vide les données mises en mémoire tampon dans le flux sous-jacent, dans notre cas, un flux de sortie canalisé ou le flux de sortie.

Le flux imbriqué peut être utilisé comme FilterOutputStream peut également être utilisé sur ObjectOutputStream.







decorator