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