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