View Javadoc

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