View Javadoc

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