简体   繁体   中英

Piped I/O stream in java

I am not able to understand the purpose of piped i/o streams in java. If I write something using an outputstream, I can anyways read it again using an inputstream.

So what is the need of a pipedstream?

Pipes in Java IO provides the ability for two threads running in the same JVM to communicate. As such pipes are a common source or destination of data.

A PipedInputStream should be connected to a PipedOutputStream . The data written to the PipedOutputStream by one thread, can thus be read from the connected PipedInputStream by another thread

Normal Java IO does not support streaming to the same stream from multiple threads.

I think its supposed to be for reading and writing in a multi-threaded application. Where you can write in a thread and read in the other one, without flushing the data.

Short motivation:

  1. Separation of concerns (always good - in this case it helps split your code into reading and writing part)
  2. Multithreading (previous point lead to "easy" (its never easy :D) parallelization)

Long explanation/example:

Imagine you have "producer-consumer" like application. You have one part of your code that generates output and you want provide it with place to where write data to. For example:

void generateLines(int numberOfLines, OutputStream target);

There is only single responsibility of this component ie it "produces" lines and it doesnt know where the lines are written to. You just call it like generateLines(5, System.out) or generateLines(100, fileOutputStream) . But imagine you want to assemble "pipeline" ie you do not want to store/print the data but instead you want to pass them to another component "consumer".

You could have component with signature like that:

int countLines(InputStream source);

Only thing this does is it reads data from InputStream which is provided externally.

Now thanks to "Piped" streams you can glue those two component together by creating "pipe" like:

PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream(pos, 1024);

Then you can run two threads, one that generates data and another that consumes them. Pipe api is really convenient, reading/writing is blocking (see javadoc for more details) so the usage is really simple/convenient.

// Withing main thread start generating of x lines into pos OutputStream
generateLines(50000, pos);
// Spawn new thread within which we consume pipe from its InputStream end
Executors.newCachedThreadPool().submit(() -> {
   pis.read();
   // The rest of "reading-loop" omitted for sake of simplicity...
});

Of course this example is dummy but one can easily imagine use cases like "generating huge xml" (produce) into writable stream and "compressing/validating" (consume) it and so on.

Maybe there is better example but personally I use those pipes for producer-consumer jobs as described before.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM