• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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         {
__pool.start()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 
Job(InputStream in,OutputStream out)77         Job(InputStream in,OutputStream out)
78         {
79             this.in=in;
80             this.out=out;
81             this.read=null;
82             this.write=null;
83         }
Job(Reader read,Writer write)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          */
run()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      */
copyThread(InputStream in, OutputStream out)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      */
copy(InputStream in, OutputStream out)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      */
copyThread(Reader in, Writer out)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      */
copy(Reader in, Writer out)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      */
copy(InputStream in, OutputStream out, long byteCount)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
read()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      */
getNullWriter()512     public static Writer getNullWriter()
513     {
514         return __nullWriter;
515     }
516 
517     /* ------------------------------------------------------------ */
518     /**
519      * @return An writer to nowhere
520      */
getNullPrintWriter()521     public static PrintWriter getNullPrintWriter()
522     {
523         return __nullPrintWriter;
524     }
525 
526     /* ------------------------------------------------------------ */
527     /* ------------------------------------------------------------ */
528     private static class NullWrite extends Writer
529     {
530         @Override
close()531         public void close(){}
532         @Override
flush()533         public void flush(){}
534         @Override
write(char[]b)535         public void write(char[]b){}
536         @Override
write(char[]b,int o,int l)537         public void write(char[]b,int o,int l){}
538         @Override
write(int b)539         public void write(int b){}
540         @Override
write(String s)541         public void write(String s){}
542         @Override
write(String s,int o,int l)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 
557