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.InputStreamReader;
    23  import java.io.OutputStream;
    24  import java.io.PrintWriter;
    25  import java.io.Reader;
    26  import java.io.StringWriter;
    27  import java.io.Writer;
    28
    29  import org.mortbay.log.Log;
    30  import org.mortbay.thread.BoundedThreadPool;
    31
    32  /* ======================================================================== */
    33  /** IO Utilities.
    34   * Provides stream handling utilities in
    35   * singleton Threadpool implementation accessed by static members.
    36   */
    37  public class IO extends BoundedThreadPool
    38  {
    39      /* ------------------------------------------------------------------- */
    40      public final static String
    41          CRLF      = "\015\012";
    42
    43      /* ------------------------------------------------------------------- */
    44      public final static byte[]
    45          CRLF_BYTES    = {(byte)'\015',(byte)'\012'};
    46
    47      /* ------------------------------------------------------------------- */
    48      public static int bufferSize = 2*8192;
    49
    50      /* ------------------------------------------------------------------- */
    51      // TODO get rid of this singleton!
    52      private static class Singleton {
    53          static final IO __instance=new IO();
    54          static
    55          {
    56              try{__instance.start();}
    57              catch(Exception e){Log.warn(e); System.exit(1);}
    58          }
    59      }
    60
    61      /* ------------------------------------------------------------------- */
    62      public static IO instance()
    63      {
    64          return Singleton.__instance;
    65      }
    66
    67      /* ------------------------------------------------------------------- */
    68      static class Job implements Runnable
    69      {
    70          InputStream in;
    71          OutputStream out;
    72          Reader read;
    73          Writer write;
    74
    75          Job(InputStream in,OutputStream out)
    76          {
    77              this.in=in;
    78              this.out=out;
    79              this.read=null;
    80              this.write=null;
    81          }
    82          Job(Reader read,Writer write)
    83          {
    84              this.in=null;
    85              this.out=null;
    86              this.read=read;
    87              this.write=write;
    88          }
    89
    90          /* ------------------------------------------------------------ */
    91          /*
    92           * @see java.lang.Runnable#run()
    93           */
    94          public void run()
    95          {
    96              try {
    97                  if (in!=null)
    98                      copy(in,out,-1);
    99                  else
    100                     copy(read,write,-1);
    101             }
    102             catch(IOException e)
    103             {
    104                 Log.ignore(e);
    105                 try{
    106                     if (out!=null)
    107                         out.close();
    108                     if (write!=null)
    109                         write.close();
    110                 }
    111                 catch(IOException e2)
    112                 {
    113                     Log.ignore(e2);
    114                 }
    115             }
    116         }
    117     }
    118
    119     /* ------------------------------------------------------------------- */
    120     /** Copy Stream in to Stream out until EOF or exception.
    121      * in own thread
    122      */
    123     public static void copyThread(InputStream in, OutputStream out)
    124     {
    125         try{
    126             Job job=new Job(in,out);
    127             if (!instance().dispatch(job))
    128                 job.run();
    129         }
    130         catch(Exception e)
    131         {
    132             Log.warn(e);
    133         }
    134     }
    135
    136     /* ------------------------------------------------------------------- */
    137     /** Copy Stream in to Stream out until EOF or exception.
    138      */
    139     public static void copy(InputStream in, OutputStream out)
    140          throws IOException
    141     {
    142         copy(in,out,-1);
    143     }
    144
    145     /* ------------------------------------------------------------------- */
    146     /** Copy Stream in to Stream out until EOF or exception
    147      * in own thread
    148      */
    149     public static void copyThread(Reader in, Writer out)
    150     {
    151         try
    152         {
    153             Job job=new Job(in,out);
    154             if (!instance().dispatch(job))
    155                 job.run();
    156         }
    157         catch(Exception e)
    158         {
    159             Log.warn(e);
    160         }
    161     }
    162
    163     /* ------------------------------------------------------------------- */
    164     /** Copy Reader to Writer out until EOF or exception.
    165      */
    166     public static void copy(Reader in, Writer out)
    167          throws IOException
    168     {
    169         copy(in,out,-1);
    170     }
    171
    172     /* ------------------------------------------------------------------- */
    173     /** Copy Stream in to Stream for byteCount bytes or until EOF or exception.
    174      */
    175     public static void copy(InputStream in,
    176                             OutputStream out,
    177                             long byteCount)
    178          throws IOException
    179     {
    180         byte buffer[] = new byte[bufferSize];
    181         int len=bufferSize;
    182
    183         if (byteCount>=0)
    184         {
    185             while (byteCount>0)
    186             {
    187                 if (byteCount<bufferSize)
    188                     len=in.read(buffer,0,(int)byteCount);
    189                 else
    190                     len=in.read(buffer,0,bufferSize);
    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 an input stream, and logs exceptions
    364      *
    365      * @param is the input stream to close
    366      */
    367     public static void close(InputStream is)
    368     {
    369         try
    370         {
    371             if (is != null)
    372                 is.close();
    373         }
    374         catch (IOException e)
    375         {
    376             Log.ignore(e);
    377         }
    378     }
    379
    380     /* ------------------------------------------------------------ */
    381     public static byte[] readBytes(InputStream in)
    382         throws IOException
    383     {
    384         ByteArrayOutputStream bout = new ByteArrayOutputStream();
    385         copy(in,bout);
    386         return bout.toByteArray();
    387     }
    388
    389     /* ------------------------------------------------------------ */
    390     /**
    391      * closes an output stream, and logs exceptions
    392      *
    393      * @param os the output stream to close
    394      */
    395     public static void close(OutputStream os)
    396     {
    397         try
    398         {
    399             if (os != null)
    400                 os.close();
    401         }
    402         catch (IOException e)
    403         {
    404             Log.ignore(e);
    405         }
    406     }
    407
    408     /* ------------------------------------------------------------ */
    409     /**
    410      * @return An outputstream to nowhere
    411      */
    412     public static OutputStream getNullStream()
    413     {
    414         return __nullStream;
    415     }
    416
    417     /* ------------------------------------------------------------ */
    418     /**
    419      * @return An outputstream to nowhere
    420      */
    421     public static InputStream getClosedStream()
    422     {
    423         return __closedStream;
    424     }
    425
    426     /* ------------------------------------------------------------ */
    427     /* ------------------------------------------------------------ */
    428     private static class NullOS extends OutputStream
    429     {
    430         public void close(){}
    431         public void flush(){}
    432         public void write(byte[]b){}
    433         public void write(byte[]b,int i,int l){}
    434         public void write(int b){}
    435     }
    436     private static NullOS __nullStream = new NullOS();
    437
    438
    439     /* ------------------------------------------------------------ */
    440     /* ------------------------------------------------------------ */
    441     private static class ClosedIS extends InputStream
    442     {
    443         public int read() throws IOException
    444         {
    445             return -1;
    446         }
    447     }
    448     private static ClosedIS __closedStream = new ClosedIS();
    449
    450     /* ------------------------------------------------------------ */
    451     /**
    452      * @return An writer to nowhere
    453      */
    454     public static Writer getNullWriter()
    455     {
    456         return __nullWriter;
    457     }
    458
    459     /* ------------------------------------------------------------ */
    460     /* ------------------------------------------------------------ */
    461     private static class NullWrite extends Writer
    462     {
    463         public void close(){}
    464         public void flush(){}
    465         public void write(char[]b){}
    466         public void write(char[]b,int o,int l){}
    467         public void write(int b){}
    468         public void write(String s){}
    469         public void write(String s,int o,int l){}
    470     }
    471     private static NullWrite __nullWriter = new NullWrite();
    472
    473 }
    474
    475
    476
    477
    478
    479
    480
    481
    482