package com.knowgate.dfs; //-< Pipe.java >-----------------------------------------------------*--------* // JSYNC Version 1.04 (c) 1998 GARRET * ? * // (Java synchronization classes) * /\| * // * / \ * // Created: 20-Jun-98 K.A. Knizhnik * / [] \ * // Last update: 6-Jul-98 K.A. Knizhnik * GARRET * // http://www.garret.ru/~knizhnik/java.html * //-------------------------------------------------------------------*--------* // Link two existed input and output threads. //-------------------------------------------------------------------*--------* import java.io.InputStream; import java.io.FileInputStream; import java.io.BufferedInputStream; import java.io.OutputStream; import java.io.IOException; import java.io.FileNotFoundException; import com.knowgate.debug.DebugFile; /** This class links input and output streams so that data taken from input * stream is transfered to the output stream. This class can be used to * connect standard input/ouput stream of Java application with * output/input streams of spawned child process, so that all user's input is * redirected to the child and all it's output is visible for the user.<P> * * This class starts a thread, which transfers data from input stream to * output stream until End Of File is reached or IOException caused by IO * error is catched. * @author Konstantin Knizhnik * @version 1.04 */ public class StreamPipe { /** Default size of buffer used to transfer data from the input * stream to the output stream. */ private static final int defaultBufferSize = 8000; boolean bSynchronous; /** * <b>Create synchronous stream conector.</b> * between() methods do not return until end of input stream is reached and * written into ouput stream. */ public StreamPipe () { bSynchronous = true; } /** * <b>Create synchronous or asynchronous stream conector.</b> * between() methods do not return until end of input stream is reached and * written into ouput stream. */ public StreamPipe (boolean bSync) { bSynchronous = bSync; } // ------------------------------------------------------------------------- private static void pipe (InputStream in, OutputStream out, int bufferSize, boolean autoFlush) throws IOException { int total = 0; byte[] buffer = new byte[bufferSize]; int length; while ((length = in.read(buffer)) > 0) { out.write(buffer, 0, length); if (autoFlush) out.flush(); total += length; } } // pipe // ------------------------------------------------------------------------- /** Establish connection between input and output streams with specified size of buffer used for data transfer. * @param in input stream * @param out output stream * @param bufferSize size of buffer used to transfer data from the input stream to the output stream * @param autoFlush if set to <b>true</b> OutputStream.flush() method will be called each time bufferSize bytes are written into output stream */ public void between(InputStream in,OutputStream out, int bufferSize, boolean autoFlush) throws IOException { if (bSynchronous) pipe(in, out, bufferSize, autoFlush); else (new PipeThread(in, out, bufferSize, autoFlush)).start(); } /** Establish connection between input and output streams with specified size of buffer used for data transfer and no auto-flush. * @param in input stream * @param out output stream */ public void between(InputStream in, OutputStream out, int bufferSize) throws IOException { if (bSynchronous) pipe(in, out, bufferSize, false); else (new PipeThread(in, out, bufferSize, false)).start(); } /** Establish connection between input and output streams with default buffer size and no auto-flush. * @param in input stream * @param out output stream */ public void between(InputStream in, OutputStream out) throws IOException { if (bSynchronous) pipe(in, out, defaultBufferSize, false); else (new PipeThread(in, out, defaultBufferSize, false)).start(); } // ------------------------------------------------------------------------- /** Establish synchronous connection between a file and an output stream * with specified size of buffer used for data transfer. * autoFlush is set to <b>false</b> and buffer size is set to 8000 bytes. * @param sFilePath input stream * @param oOutStrm output stream * @since 3.0 */ public static void between(String sFilePath, OutputStream oOutStrm) throws IOException,FileNotFoundException { FileInputStream oFileIoStrm = new FileInputStream(sFilePath); BufferedInputStream oBfIoStrm = new BufferedInputStream(oFileIoStrm, defaultBufferSize); pipe(oBfIoStrm, oOutStrm, 8000, false); oBfIoStrm.close(); oFileIoStrm.close(); } // between } // --------------------------------------------------------------------------- final class PipeThread extends Thread { InputStream in; OutputStream out; byte[] buffer; boolean flush; PipeThread(InputStream in, OutputStream out, int bufferSize, boolean autoFlush) { this.in = in; this.out = out; buffer = new byte[bufferSize]; flush = autoFlush; } public void run() { int total = 0; try { int length; while ((length = in.read(buffer)) > 0) { if (DebugFile.trace) DebugFile.writeln("OutputStream.write(byte[], 0, " + String.valueOf(length)+")"); out.write(buffer, 0, length); if (flush) out.flush(); total += length; } } catch(IOException ex) { } } }