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
231         {
232             while (true)
233             {
234                 len=in.read(buffer,0,bufferSize);
235                 if (len==-1)
236                     break;
237                 out.write(buffer,0,len);
238             }
239         }
240     }
241 
242     /* ------------------------------------------------------------ */
243     /** Copy files or directories
244      * @param from
245      * @param to
246      * @throws IOException
247      */
248     public static void copy(File from,File to) throws IOException
249     {
250         if (from.isDirectory())
251             copyDir(from,to);
252         else
253             copyFile(from,to);
254     }
255 
256     /* ------------------------------------------------------------ */
257     public static void copyDir(File from,File to) throws IOException
258     {
259         if (to.exists())
260         {
261             if (!to.isDirectory())
262                 throw new IllegalArgumentException(to.toString());
263         }
264         else
265             to.mkdirs();
266         
267         File[] files = from.listFiles();
268         if (files!=null)
269         {
270             for (int i=0;i<files.length;i++)
271             {
272                 String name = files[i].getName();
273                 if (".".equals(name) || "..".equals(name))
274                     continue;
275                 copy(files[i],new File(to,name));
276             }
277         }
278     }
279     
280     /* ------------------------------------------------------------ */
281     public static void copyFile(File from,File to) throws IOException
282     {
283         FileInputStream in=new FileInputStream(from);
284         FileOutputStream out=new FileOutputStream(to);
285         copy(in,out);
286         in.close();
287         out.close();
288     }
289     
290     /* ------------------------------------------------------------ */
291     /** Read input stream to string.
292      */
293     public static String toString(InputStream in)
294         throws IOException
295     {
296         return toString(in,null);
297     }
298     
299     /* ------------------------------------------------------------ */
300     /** Read input stream to string.
301      */
302     public static String toString(InputStream in,String encoding)
303         throws IOException
304     {
305         StringWriter writer=new StringWriter();
306         InputStreamReader reader = encoding==null?new InputStreamReader(in):new InputStreamReader(in,encoding);
307         
308         copy(reader,writer);
309         return writer.toString();
310     }
311     
312     /* ------------------------------------------------------------ */
313     /** Read input stream to string.
314      */
315     public static String toString(Reader in)
316         throws IOException
317     {
318         StringWriter writer=new StringWriter();
319         copy(in,writer);
320         return writer.toString();
321     }
322 
323 
324     /* ------------------------------------------------------------ */
325     /** Delete File.
326      * This delete will recursively delete directories - BE CAREFULL
327      * @param file The file to be deleted.
328      */
329     public static boolean delete(File file)
330     {
331         if (!file.exists())
332             return false;
333         if (file.isDirectory())
334         {
335             File[] files = file.listFiles();
336             for (int i=0;files!=null && i<files.length;i++)
337                 delete(files[i]);
338         }
339         return file.delete();
340     }
341 
342     /* ------------------------------------------------------------ */
343     /**
344      * closes an input stream, and logs exceptions
345      *
346      * @param is the input stream to close
347      */
348     public static void close(InputStream is)
349     {
350         try
351         {
352             if (is != null)
353                 is.close();
354         }
355         catch (IOException e)
356         {
357             Log.ignore(e);
358         }
359     }
360 
361     /**
362      * closes a reader, and logs exceptions
363      * 
364      * @param reader the reader to close
365      */
366     public static void close(Reader reader)
367     {
368         try
369         {
370             if (reader != null)
371                 reader.close();
372         } catch (IOException e)
373         {
374             Log.ignore(e);
375         }
376     }
377 
378     /**
379      * closes a writer, and logs exceptions
380      * 
381      * @param writer the writer to close
382      */
383     public static void close(Writer writer)
384     {
385         try
386         {
387             if (writer != null)
388                 writer.close();
389         } catch (IOException e)
390         {
391             Log.ignore(e);
392         }
393     }
394     
395     /* ------------------------------------------------------------ */
396     public static byte[] readBytes(InputStream in)
397         throws IOException
398     {
399         ByteArrayOutputStream bout = new ByteArrayOutputStream();
400         copy(in,bout);
401         return bout.toByteArray();
402     }
403     
404     /* ------------------------------------------------------------ */
405     /**
406      * closes an output stream, and logs exceptions
407      *
408      * @param os the output stream to close
409      */
410     public static void close(OutputStream os)
411     {
412         try
413         {
414             if (os != null)
415                 os.close();
416         }
417         catch (IOException e)
418         {
419             Log.ignore(e);
420         }
421     }
422 
423     /* ------------------------------------------------------------ */
424     /** 
425      * @return An outputstream to nowhere
426      */
427     public static OutputStream getNullStream()
428     {
429         return __nullStream;
430     }
431 
432     /* ------------------------------------------------------------ */
433     /** 
434      * @return An outputstream to nowhere
435      */
436     public static InputStream getClosedStream()
437     {
438         return __closedStream;
439     }
440     
441     /* ------------------------------------------------------------ */
442     /* ------------------------------------------------------------ */
443     private static class NullOS extends OutputStream                                    
444     {
445         public void close(){}
446         public void flush(){}
447         public void write(byte[]b){}
448         public void write(byte[]b,int i,int l){}
449         public void write(int b){}
450     }
451     private static NullOS __nullStream = new NullOS();
452 
453     
454     /* ------------------------------------------------------------ */
455     /* ------------------------------------------------------------ */
456     private static class ClosedIS extends InputStream                                    
457     {
458         public int read() throws IOException
459         {
460             return -1;
461         }
462     }
463     private static ClosedIS __closedStream = new ClosedIS();
464     
465     /* ------------------------------------------------------------ */
466     /** 
467      * @return An writer to nowhere
468      */
469     public static Writer getNullWriter()
470     {
471         return __nullWriter;
472     }
473     
474     /* ------------------------------------------------------------ */
475     /** 
476      * @return An writer to nowhere
477      */
478     public static PrintWriter getNullPrintWriter()
479     {
480         return __nullPrintWriter;
481     }
482     
483     /* ------------------------------------------------------------ */
484     /* ------------------------------------------------------------ */
485     private static class NullWrite extends Writer                                    
486     {
487         public void close(){}
488         public void flush(){}
489         public void write(char[]b){}
490         public void write(char[]b,int o,int l){}
491         public void write(int b){}
492         public void write(String s){}
493         public void write(String s,int o,int l){}
494     }
495     private static NullWrite __nullWriter = new NullWrite();
496     private static PrintWriter __nullPrintWriter = new PrintWriter(__nullWriter);
497 }
498 
499 
500 
501 
502 
503 
504 
505 
506