View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 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.File;
22  import java.io.FileInputStream;
23  import java.io.FileOutputStream;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.io.InputStreamReader;
27  import java.io.OutputStream;
28  import java.io.PrintWriter;
29  import java.io.Reader;
30  import java.io.StringWriter;
31  import java.io.Writer;
32  import java.nio.charset.Charset;
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 final 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         try (InputStream in=new FileInputStream(from);
303                 OutputStream out=new FileOutputStream(to))
304         {
305             copy(in,out);
306         }
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,(Charset)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         return toString(in, encoding==null?null:Charset.forName(encoding));
325     }
326 
327     /** Read input stream to string.
328      */
329     public static String toString(InputStream in, Charset encoding)
330             throws IOException
331     {
332         StringWriter writer=new StringWriter();
333         InputStreamReader reader = encoding==null?new InputStreamReader(in):new InputStreamReader(in,encoding);
334 
335         copy(reader,writer);
336         return writer.toString();
337     }
338 
339     /* ------------------------------------------------------------ */
340     /** Read input stream to string.
341      */
342     public static String toString(Reader in)
343         throws IOException
344     {
345         StringWriter writer=new StringWriter();
346         copy(in,writer);
347         return writer.toString();
348     }
349 
350 
351     /* ------------------------------------------------------------ */
352     /** Delete File.
353      * This delete will recursively delete directories - BE CAREFULL
354      * @param file The file to be deleted.
355      */
356     public static boolean delete(File file)
357     {
358         if (!file.exists())
359             return false;
360         if (file.isDirectory())
361         {
362             File[] files = file.listFiles();
363             for (int i=0;files!=null && i<files.length;i++)
364                 delete(files[i]);
365         }
366         return file.delete();
367     }
368 
369     /* ------------------------------------------------------------ */
370     /**
371      * closes an input stream, and logs exceptions
372      *
373      * @param is the input stream to close
374      */
375     public static void close(InputStream is)
376     {
377         try
378         {
379             if (is != null)
380                 is.close();
381         }
382         catch (IOException e)
383         {
384             LOG.ignore(e);
385         }
386     }
387 
388     /**
389      * closes a reader, and logs exceptions
390      * 
391      * @param reader the reader to close
392      */
393     public static void close(Reader reader)
394     {
395         try
396         {
397             if (reader != null)
398                 reader.close();
399         } catch (IOException e)
400         {
401             LOG.ignore(e);
402         }
403     }
404 
405     /**
406      * closes a writer, and logs exceptions
407      * 
408      * @param writer the writer to close
409      */
410     public static void close(Writer writer)
411     {
412         try
413         {
414             if (writer != null)
415                 writer.close();
416         } catch (IOException e)
417         {
418             LOG.ignore(e);
419         }
420     }
421     
422     /* ------------------------------------------------------------ */
423     public static byte[] readBytes(InputStream in)
424         throws IOException
425     {
426         ByteArrayOutputStream bout = new ByteArrayOutputStream();
427         copy(in,bout);
428         return bout.toByteArray();
429     }
430     
431     /* ------------------------------------------------------------ */
432     /**
433      * closes an output stream, and logs exceptions
434      *
435      * @param os the output stream to close
436      */
437     public static void close(OutputStream os)
438     {
439         try
440         {
441             if (os != null)
442                 os.close();
443         }
444         catch (IOException e)
445         {
446             LOG.ignore(e);
447         }
448     }
449 
450     /* ------------------------------------------------------------ */
451     /** 
452      * @return An outputstream to nowhere
453      */
454     public static OutputStream getNullStream()
455     {
456         return __nullStream;
457     }
458 
459     /* ------------------------------------------------------------ */
460     /** 
461      * @return An outputstream to nowhere
462      */
463     public static InputStream getClosedStream()
464     {
465         return __closedStream;
466     }
467     
468     /* ------------------------------------------------------------ */
469     /* ------------------------------------------------------------ */
470     private static class NullOS extends OutputStream                                    
471     {
472         @Override
473         public void close(){}
474         @Override
475         public void flush(){}
476         @Override
477         public void write(byte[]b){}
478         @Override
479         public void write(byte[]b,int i,int l){}
480         @Override
481         public void write(int b){}
482     }
483     private static NullOS __nullStream = new NullOS();
484 
485     
486     /* ------------------------------------------------------------ */
487     /* ------------------------------------------------------------ */
488     private static class ClosedIS extends InputStream                                    
489     {
490         @Override
491         public int read() throws IOException
492         {
493             return -1;
494         }
495     }
496     private static ClosedIS __closedStream = new ClosedIS();
497     
498     /* ------------------------------------------------------------ */
499     /** 
500      * @return An writer to nowhere
501      */
502     public static Writer getNullWriter()
503     {
504         return __nullWriter;
505     }
506     
507     /* ------------------------------------------------------------ */
508     /** 
509      * @return An writer to nowhere
510      */
511     public static PrintWriter getNullPrintWriter()
512     {
513         return __nullPrintWriter;
514     }
515     
516     /* ------------------------------------------------------------ */
517     /* ------------------------------------------------------------ */
518     private static class NullWrite extends Writer                                    
519     {
520         @Override
521         public void close(){}
522         @Override
523         public void flush(){}
524         @Override
525         public void write(char[]b){}
526         @Override
527         public void write(char[]b,int o,int l){}
528         @Override
529         public void write(int b){}
530         @Override
531         public void write(String s){}
532         @Override
533         public void write(String s,int o,int l){}
534     }
535     private static NullWrite __nullWriter = new NullWrite();
536     private static PrintWriter __nullPrintWriter = new PrintWriter(__nullWriter);
537 }
538 
539 
540 
541 
542 
543 
544 
545 
546