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