001: // ========================================================================
002: // Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
003: // ------------------------------------------------------------------------
004: // Licensed under the Apache License, Version 2.0 (the "License");
005: // you may not use this file except in compliance with the License.
006: // You may obtain a copy of the License at
007: // http://www.apache.org/licenses/LICENSE-2.0
008: // Unless required by applicable law or agreed to in writing, software
009: // distributed under the License is distributed on an "AS IS" BASIS,
010: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011: // See the License for the specific language governing permissions and
012: // limitations under the License.
013: // ========================================================================
014:
015: package org.mortbay.util;
016:
017: import java.io.ByteArrayOutputStream;
018: import java.io.File;
019: import java.io.FileInputStream;
020: import java.io.FileOutputStream;
021: import java.io.IOException;
022: import java.io.InputStream;
023: import java.io.OutputStream;
024: import java.io.Reader;
025: import java.io.Writer;
026:
027: import org.mortbay.log.Log;
028: import org.mortbay.thread.BoundedThreadPool;
029:
030: /* ======================================================================== */
031: /** IO Utilities.
032: * Provides stream handling utilities in
033: * singleton Threadpool implementation accessed by static members.
034: */
035: public class IO extends BoundedThreadPool {
036: /* ------------------------------------------------------------------- */
037: public final static String CRLF = "\015\012";
038:
039: /* ------------------------------------------------------------------- */
040: public final static byte[] CRLF_BYTES = { (byte) '\015',
041: (byte) '\012' };
042:
043: /* ------------------------------------------------------------------- */
044: public static int bufferSize = 2 * 8192;
045:
046: /* ------------------------------------------------------------------- */
047: // TODO get rid of this singleton!
048: private static class Singleton {
049: static final IO __instance = new IO();
050: static {
051: try {
052: __instance.start();
053: } catch (Exception e) {
054: Log.warn(e);
055: System.exit(1);
056: }
057: }
058: }
059:
060: public static IO instance() {
061: return Singleton.__instance;
062: }
063:
064: /* ------------------------------------------------------------------- */
065: static class Job implements Runnable {
066: InputStream in;
067: OutputStream out;
068: Reader read;
069: Writer write;
070:
071: Job(InputStream in, OutputStream out) {
072: this .in = in;
073: this .out = out;
074: this .read = null;
075: this .write = null;
076: }
077:
078: Job(Reader read, Writer write) {
079: this .in = null;
080: this .out = null;
081: this .read = read;
082: this .write = write;
083: }
084:
085: /* ------------------------------------------------------------ */
086: /*
087: * @see java.lang.Runnable#run()
088: */
089: public void run() {
090: try {
091: if (in != null)
092: copy(in, out, -1);
093: else
094: copy(read, write, -1);
095: } catch (IOException e) {
096: Log.ignore(e);
097: try {
098: if (out != null)
099: out.close();
100: if (write != null)
101: write.close();
102: } catch (IOException e2) {
103: Log.ignore(e2);
104: }
105: }
106: }
107: }
108:
109: /* ------------------------------------------------------------------- */
110: /** Copy Stream in to Stream out until EOF or exception.
111: * in own thread
112: */
113: public static void copyThread(InputStream in, OutputStream out) {
114: try {
115: Job job = new Job(in, out);
116: if (!instance().dispatch(job))
117: job.run();
118: } catch (Exception e) {
119: Log.warn(e);
120: }
121: }
122:
123: /* ------------------------------------------------------------------- */
124: /** Copy Stream in to Stream out until EOF or exception.
125: */
126: public static void copy(InputStream in, OutputStream out)
127: throws IOException {
128: copy(in, out, -1);
129: }
130:
131: /* ------------------------------------------------------------------- */
132: /** Copy Stream in to Stream out until EOF or exception
133: * in own thread
134: */
135: public static void copyThread(Reader in, Writer out) {
136: try {
137: Job job = new Job(in, out);
138: if (!instance().dispatch(job))
139: job.run();
140: } catch (Exception e) {
141: Log.warn(e);
142: }
143: }
144:
145: /* ------------------------------------------------------------------- */
146: /** Copy Reader to Writer out until EOF or exception.
147: */
148: public static void copy(Reader in, Writer out) throws IOException {
149: copy(in, out, -1);
150: }
151:
152: /* ------------------------------------------------------------------- */
153: /** Copy Stream in to Stream for byteCount bytes or until EOF or exception.
154: */
155: public static void copy(InputStream in, OutputStream out,
156: long byteCount) throws IOException {
157: byte buffer[] = new byte[bufferSize];
158: int len = bufferSize;
159:
160: if (byteCount >= 0) {
161: while (byteCount > 0) {
162: if (byteCount < bufferSize)
163: len = in.read(buffer, 0, (int) byteCount);
164: else
165: len = in.read(buffer, 0, bufferSize);
166:
167: if (len == -1)
168: break;
169:
170: byteCount -= len;
171: out.write(buffer, 0, len);
172: }
173: } else {
174: while (true) {
175: len = in.read(buffer, 0, bufferSize);
176: if (len < 0)
177: break;
178: out.write(buffer, 0, len);
179: }
180: }
181: }
182:
183: /* ------------------------------------------------------------------- */
184: /** Copy Reader to Writer for byteCount bytes or until EOF or exception.
185: */
186: public static void copy(Reader in, Writer out, long byteCount)
187: throws IOException {
188: char buffer[] = new char[bufferSize];
189: int len = bufferSize;
190:
191: if (byteCount >= 0) {
192: while (byteCount > 0) {
193: if (byteCount < bufferSize)
194: len = in.read(buffer, 0, (int) byteCount);
195: else
196: len = in.read(buffer, 0, bufferSize);
197:
198: if (len == -1)
199: break;
200:
201: byteCount -= len;
202: out.write(buffer, 0, len);
203: }
204: } else {
205: while (true) {
206: len = in.read(buffer, 0, bufferSize);
207: if (len == -1)
208: break;
209: out.write(buffer, 0, len);
210: }
211: }
212: }
213:
214: /* ------------------------------------------------------------ */
215: /** Copy files or directories
216: * @param from
217: * @param to
218: * @throws IOException
219: */
220: public static void copy(File from, File to) throws IOException {
221: if (from.isDirectory())
222: copyDir(from, to);
223: else
224: copyFile(from, to);
225: }
226:
227: /* ------------------------------------------------------------ */
228: public static void copyDir(File from, File to) throws IOException {
229: if (to.exists()) {
230: if (!to.isDirectory())
231: throw new IllegalArgumentException(to.toString());
232: } else
233: to.mkdirs();
234:
235: File[] files = from.listFiles();
236: if (files != null) {
237: for (int i = 0; i < files.length; i++) {
238: String name = files[i].getName();
239: if (".".equals(name) || "..".equals(name))
240: continue;
241: copy(files[i], new File(to, name));
242: }
243: }
244: }
245:
246: /* ------------------------------------------------------------ */
247: public static void copyFile(File from, File to) throws IOException {
248: FileInputStream in = new FileInputStream(from);
249: FileOutputStream out = new FileOutputStream(to);
250: copy(in, out);
251: in.close();
252: out.close();
253: }
254:
255: /* ------------------------------------------------------------ */
256: /** Read input stream to string.
257: */
258: public static String toString(InputStream in) throws IOException {
259: ByteArrayOutputStream out = new ByteArrayOutputStream();
260: copy(in, out);
261: return new String(out.toByteArray());
262: }
263:
264: /* ------------------------------------------------------------ */
265: /** Delete File.
266: * This delete will recursively delete directories - BE CAREFULL
267: * @param file The file to be deleted.
268: */
269: public static boolean delete(File file) {
270: if (!file.exists())
271: return false;
272: if (file.isDirectory()) {
273: File[] files = file.listFiles();
274: for (int i = 0; files != null && i < files.length; i++)
275: delete(files[i]);
276: }
277: return file.delete();
278: }
279:
280: /* ------------------------------------------------------------ */
281: /**
282: * closes an input stream, and logs exceptions
283: *
284: * @param is the input stream to close
285: */
286: public static void close(InputStream is) {
287: try {
288: if (is != null)
289: is.close();
290: } catch (IOException e) {
291: Log.ignore(e);
292: }
293: }
294:
295: /* ------------------------------------------------------------ */
296: public static byte[] readBytes(InputStream in) throws IOException {
297: ByteArrayOutputStream bout = new ByteArrayOutputStream();
298: copy(in, bout);
299: return bout.toByteArray();
300: }
301:
302: /* ------------------------------------------------------------ */
303: /**
304: * closes an output stream, and logs exceptions
305: *
306: * @param os the output stream to close
307: */
308: public static void close(OutputStream os) {
309: try {
310: if (os != null)
311: os.close();
312: } catch (IOException e) {
313: Log.ignore(e);
314: }
315: }
316:
317: /* ------------------------------------------------------------ */
318: /**
319: * @return An outputstream to nowhere
320: */
321: public static OutputStream getNullStream() {
322: return __nullStream;
323: }
324:
325: /* ------------------------------------------------------------ */
326: /* ------------------------------------------------------------ */
327: private static class NullOS extends OutputStream {
328: public void close() {
329: }
330:
331: public void flush() {
332: }
333:
334: public void write(byte[] b) {
335: }
336:
337: public void write(byte[] b, int i, int l) {
338: }
339:
340: public void write(int b) {
341: }
342: }
343:
344: private static NullOS __nullStream = new NullOS();
345:
346: /* ------------------------------------------------------------ */
347: /**
348: * @return An writer to nowhere
349: */
350: public static Writer getNullWriter() {
351: return __nullWriter;
352: }
353:
354: /* ------------------------------------------------------------ */
355: /* ------------------------------------------------------------ */
356: private static class NullWrite extends Writer {
357: public void close() {
358: }
359:
360: public void flush() {
361: }
362:
363: public void write(char[] b) {
364: }
365:
366: public void write(char[] b, int o, int l) {
367: }
368:
369: public void write(int b) {
370: }
371:
372: public void write(String s) {
373: }
374:
375: public void write(String s, int o, int l) {
376: }
377: }
378:
379: private static NullWrite __nullWriter = new NullWrite();
380:
381: }
|