title: Best way to Pipe InputStream to OutputStream
body: <p>I was to trying to find the best way to pipe the InputStream to OutputStream. I don't have an option to use any other libraries like Apache IO. Here is the snippet and output.</p>
  
  <pre><code>import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.nio.channels.FileChannel;
  
  public class Pipe {
      public static void main(String[] args) throws Exception {
  
          for(PipeTestCase testCase : testCases) {
              System.out.println(testCase.getApproach());
              InputStream is = new FileInputStream("D:\\in\\lft_.txt");
              OutputStream os = new FileOutputStream("D:\\in\\out.txt");
  
              long start = System.currentTimeMillis();            
              testCase.pipe(is, os);
              long end = System.currentTimeMillis();
  
              System.out.println("Execution Time = " + (end - start) + " millis");
              System.out.println("============================================");
  
              is.close();
              os.close();
          }
  
      }
  
      private static PipeTestCase[] testCases = {
  
          new PipeTestCase("Fixed Buffer Read") {         
              @Override
              public void pipe(InputStream is, OutputStream os) throws IOException {
                  byte[] buffer = new byte[1024];
                  while(is.read(buffer) &gt; -1) {
                      os.write(buffer);   
                  }
              }
          },
  
          new PipeTestCase("dynamic Buffer Read") {           
              @Override
              public void pipe(InputStream is, OutputStream os) throws IOException {
                  byte[] buffer = new byte[is.available()];
                  while(is.read(buffer) &gt; -1) {
                      os.write(buffer);   
                      buffer = new byte[is.available() + 1];
                  }
              }
          },
  
          new PipeTestCase("Byte Read") {         
              @Override
              public void pipe(InputStream is, OutputStream os) throws IOException {
                  int c; 
                  while((c = is.read()) &gt; -1) {
                      os.write(c);    
                  }
              }
          }, 
  
          new PipeTestCase("NIO Read") {          
              @Override
              public void pipe(InputStream is, OutputStream os) throws IOException {
                  FileChannel source      = ((FileInputStream) is).getChannel(); 
                  FileChannel destnation  = ((FileOutputStream) os).getChannel();
                  destnation.transferFrom(source, 0, source.size());
              }
          }, 
  
      };
  }
  
  
  abstract class PipeTestCase {
      private String approach; 
      public PipeTestCase( final String approach) {
          this.approach = approach;           
      }
  
      public String getApproach() {
          return approach;
      }
  
      public abstract void pipe(InputStream is, OutputStream os) throws IOException;
  }
  </code></pre>
  
  <p>Output (~4MB input file) :</p>
  
  <pre><code>Fixed Buffer Read
  Execution Time = 71 millis
  ============================================
  dynamic Buffer Read
  Execution Time = 167 millis
  ============================================
  Byte Read
  Execution Time = 29124 millis
  ============================================
  NIO Read
  Execution Time = 125 millis
  ============================================
  </code></pre>
  
  <p>'Dynamic Buffer Read' uses <code>available()</code> method. But it is not reliable as per java docs</p>
  
  <blockquote>
    <p>It is never correct to use the return value of this method to allocate
    a buffer intended to hold all data in this stream.</p>
  </blockquote>
  
  <p>'Byte Read' seems to be very slow.</p>
  
  <p>So 'Fixed Buffer Read' is the best option for pipe? Any thoughts?</p>