001: package com.knowgate.dfs;
002:
003: //-< Pipe.java >-----------------------------------------------------*--------*
004: // JSYNC Version 1.04 (c) 1998 GARRET * ? *
005: // (Java synchronization classes) * /\| *
006: // * / \ *
007: // Created: 20-Jun-98 K.A. Knizhnik * / [] \ *
008: // Last update: 6-Jul-98 K.A. Knizhnik * GARRET *
009: // http://www.garret.ru/~knizhnik/java.html *
010: //-------------------------------------------------------------------*--------*
011: // Link two existed input and output threads.
012: //-------------------------------------------------------------------*--------*
013:
014: import java.io.InputStream;
015: import java.io.FileInputStream;
016: import java.io.BufferedInputStream;
017: import java.io.OutputStream;
018: import java.io.IOException;
019: import java.io.FileNotFoundException;
020:
021: import com.knowgate.debug.DebugFile;
022:
023: /** This class links input and output streams so that data taken from input
024: * stream is transfered to the output stream. This class can be used to
025: * connect standard input/ouput stream of Java application with
026: * output/input streams of spawned child process, so that all user's input is
027: * redirected to the child and all it's output is visible for the user.<P>
028: *
029: * This class starts a thread, which transfers data from input stream to
030: * output stream until End Of File is reached or IOException caused by IO
031: * error is catched.
032: * @author Konstantin Knizhnik
033: * @version 1.04
034: */
035: public class StreamPipe {
036: /** Default size of buffer used to transfer data from the input
037: * stream to the output stream.
038: */
039: private static final int defaultBufferSize = 8000;
040: boolean bSynchronous;
041:
042: /**
043: * <b>Create synchronous stream conector.</b>
044: * between() methods do not return until end of input stream is reached and
045: * written into ouput stream.
046: */
047: public StreamPipe() {
048: bSynchronous = true;
049: }
050:
051: /**
052: * <b>Create synchronous or asynchronous stream conector.</b>
053: * between() methods do not return until end of input stream is reached and
054: * written into ouput stream.
055: */
056: public StreamPipe(boolean bSync) {
057: bSynchronous = bSync;
058: }
059:
060: // -------------------------------------------------------------------------
061:
062: private static void pipe(InputStream in, OutputStream out,
063: int bufferSize, boolean autoFlush) throws IOException {
064:
065: if (DebugFile.trace) {
066: DebugFile.writeln("Begin StreamPipe.pipe()");
067: }
068:
069: int total = 0;
070: byte[] buffer = new byte[bufferSize];
071:
072: int length;
073: while ((length = in.read(buffer)) > 0) {
074: if (DebugFile.trace)
075: DebugFile.writeln("OutputStream.write(byte[], 0, "
076: + String.valueOf(length) + ")");
077: out.write(buffer, 0, length);
078: if (autoFlush)
079: out.flush();
080: total += length;
081: }
082:
083: if (DebugFile.trace) {
084: DebugFile.writeln("End StreamPipe.pipe() : "
085: + String.valueOf(total));
086: }
087: } // pipe
088:
089: // -------------------------------------------------------------------------
090:
091: /** Establish connection between input and output streams with specified size of buffer used for data transfer.
092: * @param in input stream
093: * @param out output stream
094: * @param bufferSize size of buffer used to transfer data from the input stream to the output stream
095: * @param autoFlush if set to <b>true</b> OutputStream.flush() method will be called each time bufferSize bytes are written into output stream
096: */
097: public void between(InputStream in, OutputStream out,
098: int bufferSize, boolean autoFlush) throws IOException {
099: if (bSynchronous)
100: pipe(in, out, bufferSize, autoFlush);
101: else
102: (new PipeThread(in, out, bufferSize, autoFlush)).start();
103: }
104:
105: /** Establish connection between input and output streams with specified size of buffer used for data transfer and no auto-flush.
106: * @param in input stream
107: * @param out output stream
108: */
109: public void between(InputStream in, OutputStream out, int bufferSize)
110: throws IOException {
111: if (bSynchronous)
112: pipe(in, out, bufferSize, false);
113: else
114: (new PipeThread(in, out, bufferSize, false)).start();
115: }
116:
117: /** Establish connection between input and output streams with default buffer size and no auto-flush.
118: * @param in input stream
119: * @param out output stream
120: */
121: public void between(InputStream in, OutputStream out)
122: throws IOException {
123:
124: if (bSynchronous)
125: pipe(in, out, defaultBufferSize, false);
126: else
127: (new PipeThread(in, out, defaultBufferSize, false)).start();
128: }
129:
130: // -------------------------------------------------------------------------
131:
132: /** Establish synchronous connection between a file and an output stream
133: * with specified size of buffer used for data transfer.
134: * autoFlush is set to <b>false</b> and buffer size is set to 8000 bytes.
135: * @param sFilePath input stream
136: * @param oOutStrm output stream
137: * @since 3.0
138: */
139: public static void between(String sFilePath, OutputStream oOutStrm)
140: throws IOException, FileNotFoundException {
141:
142: FileInputStream oFileIoStrm = new FileInputStream(sFilePath);
143: BufferedInputStream oBfIoStrm = new BufferedInputStream(
144: oFileIoStrm, defaultBufferSize);
145: pipe(oBfIoStrm, oOutStrm, 8000, false);
146: oBfIoStrm.close();
147: oFileIoStrm.close();
148: } // between
149: }
150:
151: // ---------------------------------------------------------------------------
152:
153: final class PipeThread extends Thread {
154: InputStream in;
155: OutputStream out;
156: byte[] buffer;
157: boolean flush;
158:
159: PipeThread(InputStream in, OutputStream out, int bufferSize,
160: boolean autoFlush) {
161: this .in = in;
162: this .out = out;
163: buffer = new byte[bufferSize];
164: flush = autoFlush;
165:
166: }
167:
168: public void run() {
169: if (DebugFile.trace) {
170: DebugFile.writeln("Begin StreamPipe.PipeThread.run()");
171: }
172:
173: int total = 0;
174:
175: try {
176: int length;
177: while ((length = in.read(buffer)) > 0) {
178: if (DebugFile.trace)
179: DebugFile.writeln("OutputStream.write(byte[], 0, "
180: + String.valueOf(length) + ")");
181: out.write(buffer, 0, length);
182: if (flush)
183: out.flush();
184: total += length;
185: }
186:
187: } catch (IOException ex) {
188: }
189:
190: if (DebugFile.trace) {
191: DebugFile.writeln("End StreamPipe.PipeThread.run() : "
192: + String.valueOf(total));
193: }
194: }
195: }
|