1 // ========================================================================
2 // Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
3 // ------------------------------------------------------------------------
4 // All rights reserved. This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v1.0
6 // and Apache License v2.0 which accompanies this distribution.
7 // The Eclipse Public License is available at
8 // http://www.eclipse.org/legal/epl-v10.html
9 // The Apache License v2.0 is available at
10 // http://www.opensource.org/licenses/apache2.0.php
11 // You may elect to redistribute this code under either of these licenses.
12 // ========================================================================
13
14 package org.eclipse.jetty.util;
15 import java.io.ByteArrayOutputStream;
16 import java.io.File;
17 import java.io.FileInputStream;
18 import java.io.FileOutputStream;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.InputStreamReader;
22 import java.io.OutputStream;
23 import java.io.Reader;
24 import java.io.StringWriter;
25 import java.io.Writer;
26
27 import org.eclipse.jetty.util.log.Log;
28 import org.eclipse.jetty.util.thread.QueuedThreadPool;
29
30 /* ======================================================================== */
31 /** IO Utilities.
32 * Provides stream handling utilities in
33 * singleton Threadpool implementation accessed by static members.
34 */
35 public class IO
36 {
37 /* ------------------------------------------------------------------- */
38 public final static String
39 CRLF = "\015\012";
40
41 /* ------------------------------------------------------------------- */
42 public final static byte[]
43 CRLF_BYTES = {(byte)'\015',(byte)'\012'};
44
45 /* ------------------------------------------------------------------- */
46 public static int bufferSize = 2*8192;
47
48 /* ------------------------------------------------------------------- */
49 // TODO get rid of this singleton!
50 private static class Singleton {
51 static final QueuedThreadPool __pool=new QueuedThreadPool();
52 static
53 {
54 try{__pool.start();}
55 catch(Exception e){Log.warn(e); System.exit(1);}
56 }
57 }
58
59 /* ------------------------------------------------------------------- */
60 static class Job implements Runnable
61 {
62 InputStream in;
63 OutputStream out;
64 Reader read;
65 Writer write;
66
67 Job(InputStream in,OutputStream out)
68 {
69 this.in=in;
70 this.out=out;
71 this.read=null;
72 this.write=null;
73 }
74 Job(Reader read,Writer write)
75 {
76 this.in=null;
77 this.out=null;
78 this.read=read;
79 this.write=write;
80 }
81
82 /* ------------------------------------------------------------ */
83 /*
84 * @see java.lang.Runnable#run()
85 */
86 public void run()
87 {
88 try {
89 if (in!=null)
90 copy(in,out,-1);
91 else
92 copy(read,write,-1);
93 }
94 catch(IOException e)
95 {
96 Log.ignore(e);
97 try{
98 if (out!=null)
99 out.close();
100 if (write!=null)
101 write.close();
102 }
103 catch(IOException e2)
104 {
105 Log.ignore(e2);
106 }
107 }
108 }
109 }
110
111 /* ------------------------------------------------------------------- */
112 /** Copy Stream in to Stream out until EOF or exception.
113 * in own thread
114 */
115 public static void copyThread(InputStream in, OutputStream out)
116 {
117 try{
118 Job job=new Job(in,out);
119 if (!Singleton.__pool.dispatch(job))
120 job.run();
121 }
122 catch(Exception e)
123 {
124 Log.warn(e);
125 }
126 }
127
128 /* ------------------------------------------------------------------- */
129 /** Copy Stream in to Stream out until EOF or exception.
130 */
131 public static void copy(InputStream in, OutputStream out)
132 throws IOException
133 {
134 copy(in,out,-1);
135 }
136
137 /* ------------------------------------------------------------------- */
138 /** Copy Stream in to Stream out until EOF or exception
139 * in own thread
140 */
141 public static void copyThread(Reader in, Writer out)
142 {
143 try
144 {
145 Job job=new Job(in,out);
146 if (!Singleton.__pool.dispatch(job))
147 job.run();
148 }
149 catch(Exception e)
150 {
151 Log.warn(e);
152 }
153 }
154
155 /* ------------------------------------------------------------------- */
156 /** Copy Reader to Writer out until EOF or exception.
157 */
158 public static void copy(Reader in, Writer out)
159 throws IOException
160 {
161 copy(in,out,-1);
162 }
163
164 /* ------------------------------------------------------------------- */
165 /** Copy Stream in to Stream for byteCount bytes or until EOF or exception.
166 */
167 public static void copy(InputStream in,
168 OutputStream out,
169 long byteCount)
170 throws IOException
171 {
172 byte buffer[] = new byte[bufferSize];
173 int len=bufferSize;
174
175 if (byteCount>=0)
176 {
177 while (byteCount>0)
178 {
179 int max = byteCount<bufferSize?(int)byteCount:bufferSize;
180 len=in.read(buffer,0,max);
181
182 if (len==-1)
183 break;
184
185 byteCount -= len;
186 out.write(buffer,0,len);
187 }
188 }
189 else
190 {
191 while (true)
192 {
193 len=in.read(buffer,0,bufferSize);
194 if (len<0 )
195 break;
196 out.write(buffer,0,len);
197 }
198 }
199 }
200
201 /* ------------------------------------------------------------------- */
202 /** Copy Reader to Writer for byteCount bytes or until EOF or exception.
203 */
204 public static void copy(Reader in,
205 Writer out,
206 long byteCount)
207 throws IOException
208 {
209 char buffer[] = new char[bufferSize];
210 int len=bufferSize;
211
212 if (byteCount>=0)
213 {
214 while (byteCount>0)
215 {
216 if (byteCount<bufferSize)
217 len=in.read(buffer,0,(int)byteCount);
218 else
219 len=in.read(buffer,0,bufferSize);
220
221 if (len==-1)
222 break;
223
224 byteCount -= len;
225 out.write(buffer,0,len);
226 }
227 }
228 else
229 {
230 while (true)
231 {
232 len=in.read(buffer,0,bufferSize);
233 if (len==-1)
234 break;
235 out.write(buffer,0,len);
236 }
237 }
238 }
239
240 /* ------------------------------------------------------------ */
241 /** Copy files or directories
242 * @param from
243 * @param to
244 * @throws IOException
245 */
246 public static void copy(File from,File to) throws IOException
247 {
248 if (from.isDirectory())
249 copyDir(from,to);
250 else
251 copyFile(from,to);
252 }
253
254 /* ------------------------------------------------------------ */
255 public static void copyDir(File from,File to) throws IOException
256 {
257 if (to.exists())
258 {
259 if (!to.isDirectory())
260 throw new IllegalArgumentException(to.toString());
261 }
262 else
263 to.mkdirs();
264
265 File[] files = from.listFiles();
266 if (files!=null)
267 {
268 for (int i=0;i<files.length;i++)
269 {
270 String name = files[i].getName();
271 if (".".equals(name) || "..".equals(name))
272 continue;
273 copy(files[i],new File(to,name));
274 }
275 }
276 }
277
278 /* ------------------------------------------------------------ */
279 public static void copyFile(File from,File to) throws IOException
280 {
281 FileInputStream in=new FileInputStream(from);
282 FileOutputStream out=new FileOutputStream(to);
283 copy(in,out);
284 in.close();
285 out.close();
286 }
287
288 /* ------------------------------------------------------------ */
289 /** Read input stream to string.
290 */
291 public static String toString(InputStream in)
292 throws IOException
293 {
294 return toString(in,null);
295 }
296
297 /* ------------------------------------------------------------ */
298 /** Read input stream to string.
299 */
300 public static String toString(InputStream in,String encoding)
301 throws IOException
302 {
303 StringWriter writer=new StringWriter();
304 InputStreamReader reader = encoding==null?new InputStreamReader(in):new InputStreamReader(in,encoding);
305
306 copy(reader,writer);
307 return writer.toString();
308 }
309
310 /* ------------------------------------------------------------ */
311 /** Read input stream to string.
312 */
313 public static String toString(Reader in)
314 throws IOException
315 {
316 StringWriter writer=new StringWriter();
317 copy(in,writer);
318 return writer.toString();
319 }
320
321
322 /* ------------------------------------------------------------ */
323 /** Delete File.
324 * This delete will recursively delete directories - BE CAREFULL
325 * @param file The file to be deleted.
326 */
327 public static boolean delete(File file)
328 {
329 if (!file.exists())
330 return false;
331 if (file.isDirectory())
332 {
333 File[] files = file.listFiles();
334 for (int i=0;files!=null && i<files.length;i++)
335 delete(files[i]);
336 }
337 return file.delete();
338 }
339
340 /* ------------------------------------------------------------ */
341 /**
342 * closes an input stream, and logs exceptions
343 *
344 * @param is the input stream to close
345 */
346 public static void close(InputStream is)
347 {
348 try
349 {
350 if (is != null)
351 is.close();
352 }
353 catch (IOException e)
354 {
355 Log.ignore(e);
356 }
357 }
358
359 /* ------------------------------------------------------------ */
360 public static byte[] readBytes(InputStream in)
361 throws IOException
362 {
363 ByteArrayOutputStream bout = new ByteArrayOutputStream();
364 copy(in,bout);
365 return bout.toByteArray();
366 }
367
368 /* ------------------------------------------------------------ */
369 /**
370 * closes an output stream, and logs exceptions
371 *
372 * @param os the output stream to close
373 */
374 public static void close(OutputStream os)
375 {
376 try
377 {
378 if (os != null)
379 os.close();
380 }
381 catch (IOException e)
382 {
383 Log.ignore(e);
384 }
385 }
386
387 /* ------------------------------------------------------------ */
388 /**
389 * @return An outputstream to nowhere
390 */
391 public static OutputStream getNullStream()
392 {
393 return __nullStream;
394 }
395
396 /* ------------------------------------------------------------ */
397 /**
398 * @return An outputstream to nowhere
399 */
400 public static InputStream getClosedStream()
401 {
402 return __closedStream;
403 }
404
405 /* ------------------------------------------------------------ */
406 /* ------------------------------------------------------------ */
407 private static class NullOS extends OutputStream
408 {
409 public void close(){}
410 public void flush(){}
411 public void write(byte[]b){}
412 public void write(byte[]b,int i,int l){}
413 public void write(int b){}
414 }
415 private static NullOS __nullStream = new NullOS();
416
417
418 /* ------------------------------------------------------------ */
419 /* ------------------------------------------------------------ */
420 private static class ClosedIS extends InputStream
421 {
422 public int read() throws IOException
423 {
424 return -1;
425 }
426 }
427 private static ClosedIS __closedStream = new ClosedIS();
428
429 /* ------------------------------------------------------------ */
430 /**
431 * @return An writer to nowhere
432 */
433 public static Writer getNullWriter()
434 {
435 return __nullWriter;
436 }
437
438 /* ------------------------------------------------------------ */
439 /* ------------------------------------------------------------ */
440 private static class NullWrite extends Writer
441 {
442 public void close(){}
443 public void flush(){}
444 public void write(char[]b){}
445 public void write(char[]b,int o,int l){}
446 public void write(int b){}
447 public void write(String s){}
448 public void write(String s,int o,int l){}
449 }
450 private static NullWrite __nullWriter = new NullWrite();
451
452 }
453
454
455
456
457
458
459
460
461