package org.analogweb.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;

import org.analogweb.util.logging.Log;
import org.analogweb.util.logging.Logs;

/**
 * @author snowgoose
 */
public final class IOUtils {

    private static final Log log = Logs.getLog(IOUtils.class);

    public static void closeQuietly(Closeable closeable) {
        if (closeable == null) {
            return;
        }
        try {
            closeable.close();
        } catch (IOException e) {
            // nop.
            log.log("DU000007", e, closeable);
        }
    }

    public static int copyQuietly(InputStream input, OutputStream output) {
        try {
            return copyInternal(new BufferedInputStream(input), new BufferedOutputStream(output));
        } catch (IOException e) {
            log.log("DU000008", e, input);
            return -1;
        }
    }

    public static int copy(InputStream input, OutputStream output) throws IOException {
        return copyInternal(new BufferedInputStream(input), new BufferedOutputStream(output));
    }

    private static int copyInternal(InputStream input, OutputStream output) throws IOException {
        Assertion.notNull(input, InputStream.class.getName());
        Assertion.notNull(output, OutputStream.class.getName());
        try {
            int count = 0;
            int i;
            while ((i = input.read()) != -1) {
                output.write(i);
                count++;
            }
            output.flush();
            return count;
        } finally {
            closeQuietly(input);
        }
    }

    public static String toString(InputStream in) throws IOException {
        return toString(new InputStreamReader(in));
    }

    public static String toString(Reader reader) throws IOException {
        return toString(reader, 4096);
    }

    public static String toString(Reader reader, int bufferSize) throws IOException {
        StringBuilder sb = new StringBuilder();
        char[] buffer = new char[bufferSize];
        int n = 0;
        while (-1 != (n = reader.read(buffer))) {
            sb.append(buffer, 0, n);
        }
        return sb.toString();
    }

    public static int avairable(InputStream in) {
        try {
            return in.available();
        } catch (IOException e) {
            return -1;
        }
    }
}

@@ -26,81 +26,8 @@
 l;%0A%0A
-import java.io.BufferedInputStream;%0Aimport java.io.BufferedOutputStream;%0A
 impo
@@ -189,16 +189,199 @@
 .Reader;
+%0Aimport java.nio.ByteBuffer;%0Aimport java.nio.CharBuffer;%0Aimport java.nio.channels.Channels;%0Aimport java.nio.channels.ReadableByteChannel;%0Aimport java.nio.channels.WritableByteChannel;
 %0A%0Aimport
@@ -979,81 +979,28 @@
 copy
-Internal(new BufferedInputStream
 (input
-)
 , 
-new BufferedOutputStream(output)
+output, 8192
 );%0A 
@@ -1226,81 +1226,28 @@
 copy
-Internal(new BufferedInputStream
 (input
-)
 , 
-new BufferedOutputStream(output)
+output, 8192
 );%0A 
@@ -1253,30 +1253,29 @@
     %7D%0A%0A    p
-rivate
+ublic
  static int 
@@ -1282,16 +1282,8 @@
 copy
-Internal
 (Inp
@@ -1309,33 +1309,61 @@
 putStream output
-)
+, int bufferSize)%0A           
  throws IOExcept
@@ -1508,58 +1508,228 @@
     
-try %7B%0A            int count = 0;%0A            int i
+ReadableByteChannel in = Channels.newChannel(input);%0A        WritableByteChannel out = Channels.newChannel(output);%0A        try %7B%0A            int count = 0;%0A            ByteBuffer buffer = ByteBuffer.allocate(bufferSize)
 ;%0A  
@@ -1748,26 +1748,23 @@
 ile 
-(
 (i
- = input.read()
+n.read(buffer
 ) !=
@@ -1786,20 +1786,57 @@
         
-outp
+buffer.flip();%0A                count += o
 ut.write
@@ -1836,17 +1836,22 @@
 t.write(
-i
+buffer
 );%0A     
@@ -1865,15 +1865,22 @@
     
-count++
+buffer.clear()
 ;%0A  
@@ -2407,14 +2407,18 @@
     
-char%5B%5D
+CharBuffer
  buf
@@ -2427,47 +2427,39 @@
 r = 
-new char%5BbufferSize%5D;%0A        int n = 0
+CharBuffer.allocate(bufferSize)
 ;%0A  
@@ -2480,13 +2480,8 @@
 1 !=
- (n =
  rea
@@ -2497,20 +2497,46 @@
 buffer))
-)
  %7B%0A
+            buffer.flip();%0A
         
@@ -2559,14 +2559,36 @@
 ffer
-, 0, n
+);%0A            buffer.clear(
 );%0A 

Improve IOUtils performance.