View Javadoc

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