package com.bradmcevoy.io; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class StreamUtils { private static Logger log = LoggerFactory.getLogger(StreamUtils.class); private StreamUtils() { } private static void skip(InputStream in, Long start) { try { in.skip(start); } catch (IOException ex) { throw new RuntimeException(ex); } } public static long readTo(File inFile, OutputStream out, boolean closeOut) throws ReadingException, WritingException { FileInputStream in = null; try { in = new FileInputStream(inFile); return readTo(in,out); } catch (FileNotFoundException ex) { throw new RuntimeException(ex); } finally { try { in.close(); } catch (IOException ex) { log.error("exception closing output stream",ex); } if( closeOut ) { try { out.close(); } catch (IOException ex) { log.error("exception closing outputstream",ex); } } } } public static long readTo(InputStream in, File outFile, boolean closeIn) throws ReadingException, WritingException { FileOutputStream out = null; try { out = new FileOutputStream(outFile); return readTo(in,out); } catch (FileNotFoundException ex) { throw new RuntimeException(ex); } finally { try { out.close(); } catch (IOException ex) { log.error("exception closing output stream",ex); } if( closeIn ) { try { in.close(); } catch (IOException ex) { log.error("exception closing inputstream",ex); } } } } /** * Copies data from in to out and DOES NOT close streams * * @param in * @param out * @return * @throws com.bradmcevoy.io.ReadingException * @throws com.bradmcevoy.io.WritingException */ public static long readTo(InputStream in, OutputStream out) throws ReadingException, WritingException { return readTo(in, out, false, false, null, null); } /** * Reads bytes from the input and writes them, completely, to the output. Closes both streams when * finished depending on closeIn and closeOyt * * @param in * @param out * @param closeIn * @param closeOut * @return - number of bytes written * @throws com.bradmcevoy.io.ReadingException * @throws com.bradmcevoy.io.WritingException */ public static long readTo(InputStream in, OutputStream out, boolean closeIn, boolean closeOut) throws ReadingException, WritingException { return readTo(in, out,closeIn, closeOut, null, null); } private static long readTo(InputStream in, OutputStream out, boolean closeIn, boolean closeOut, Long start, Long finish) throws ReadingException, WritingException { long cnt=0; if( start != null ) { skip(in, start); cnt = start; } byte[] buf = new byte[1024]; int s; try{ try { s = in.read(buf); } catch (IOException ex) { throw new ReadingException(ex); } catch (NullPointerException e) { log.debug( "nullpointer exception reading input stream. it happens for sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:48)"); return cnt; } long numBytes = 0; while( s > 0 ) { try { numBytes+=s; cnt+=s; out.write(buf,0,s); if( cnt > 10000 ) { out.flush(); cnt = 0; } } catch (IOException ex) { throw new WritingException(ex); } try { s = in.read(buf); } catch (IOException ex) { throw new ReadingException(ex); } } try { out.flush(); } catch (IOException ex) { throw new WritingException(ex); } return numBytes; } finally { if( closeIn ) { close(in); } if( closeOut) { close(out); } } } public static void close(OutputStream out) { if( out == null ) return ; try { out.close(); } catch (IOException ex) { log.warn("exception closing output stream",ex); } } public static void close(InputStream in) { if( in == null ) return ; try { in.close(); } catch (IOException ex) { log.warn("exception closing inputstream",ex); } } }