code: protected long copy(InputStream in, OutputStream out) throws IOException
     {
        // compare classes as in Java6 Channels.newChannel(), Java5 has a bug in newChannel().
        boolean inFile = in instanceof FileInputStream && FileInputStream.class.equals(in.getClass());
        boolean outFile = out instanceof FileOutputStream && FileOutputStream.class.equals(out.getClass());
        if (inFile && outFile)
        {
           // it's user file
           FileChannel infch = ((FileInputStream)in).getChannel();
           FileChannel outfch = ((FileOutputStream)out).getChannel();
  
           long size = 0;
           long r = 0;
           do
           {
              r = outfch.transferFrom(infch, r, infch.size());
              size += r;
           }
           while (r < infch.size());
           return size;
        }
        else
        {
           // it's user stream (not a file)
           ReadableByteChannel inch = inFile ? ((FileInputStream)in).getChannel() : Channels.newChannel(in);
           WritableByteChannel outch = outFile ? ((FileOutputStream)out).getChannel() : Channels.newChannel(out);
  
           long size = 0;
           int r = 0;
           ByteBuffer buff = ByteBuffer.allocate(IOBUFFER_SIZE);
           buff.clear();
           while ((r = inch.read(buff)) >= 0)
           {
              buff.flip();
  
              // copy all
              do
              {
                 outch.write(buff);
              }
              while (buff.hasRemaining());
  
              buff.clear();
              size += r;
           }
  
           if (outFile)
              ((FileChannel)outch).force(true); // force all data to FS
  
           return size;
        }
     }
docs: Copy input to output data using NIO.
  
  @param in
  InputStream
  @param out
  OutputStream
  @return The number of bytes, possibly zero, that were actually copied
  @throws IOException
  if error occurs