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