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