What happens when I wrap I/O streams twice?

I know that java I/O uses decorator pattern. But I feel that I understand its wrong.

Please clarify difference between two code snippets:

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

This application works according my expectations and I see result in console.

snippet 2:

I try to wrap ObjectInputStream and ObjectOutputStream twice:

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

This code just hangs up. I don't understand why. please clarify.

P.S.

It is theoretical question only.

UPDATE

Really hangs up behaviour happens because of I use pipes (According EJP answer).

for example this code works according expectations.

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

looks like if I wrap input by 10 decorators I should wrap output by 10 decorators at the same order. Is it true ?

UPDATE + 1

I noticed that problem with flushing only:

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

Answers


You're misusing piped streams. They are intended to be used by a producer thread doing writes and a consumer thread doing reads. See the Javadoc.

The piped streams share a buffer which can fill if the reading thread isn't reading, which stalls your writing thread.

Wrapping streams twice doesn't have anything to do with it, although in this case it is certainly both pointless and problematic.


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 created with Piped stream, then the input stream directly receive the data from the pipe through buffer without flushing.

Update + 1 - OutputStream created with outputstream wrapper in turn with another wrapper(commented the wrapper statments) and so on works after flush statment. Flush explicitlty flushes the buffered data to the underlying stream, in our case a piped output stream or the output stream .

Nested stream can be used like FilterOutputStream can be used on top of ObjectOutputStream also.


Need Your Help

How to pass “ID” instead of name/value from jsp to servlet?

java javascript jquery jsp servlets

I am working with JSP and servlet and I have a checkbox in which I have lot of items, each item has a name and id along with its value. These items are getting populated dynamically.

Subtract next row use current row, python dataframe

python datetime numpy pandas dataframes

I have this Pandas Dataframe in python, I want to know the time difference between two rows, next row subtract previous row, how should I approach this?

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.