View Javadoc
1   /*
2    * $Source$
3    * $Revision$
4    *
5    * Copyright (C) 2000 William Chesters
6    *
7    * Part of Melati (http://melati.org), a framework for the rapid
8    * development of clean, maintainable web applications.
9    *
10   * Melati is free software; Permission is granted to copy, distribute
11   * and/or modify this software under the terms either:
12   *
13   * a) the GNU General Public License as published by the Free Software
14   *    Foundation; either version 2 of the License, or (at your option)
15   *    any later version,
16   *
17   *    or
18   *
19   * b) any version of the Melati Software License, as published
20   *    at http://melati.org
21   *
22   * You should have received a copy of the GNU General Public License and
23   * the Melati Software License along with this program;
24   * if not, write to the Free Software Foundation, Inc.,
25   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to obtain the
26   * GNU General Public License and visit http://melati.org to obtain the
27   * Melati Software License.
28   *
29   * Feel free to contact the Developers of Melati (http://melati.org),
30   * if you would like to work out a different arrangement than the options
31   * outlined here.  It is our intention to allow Melati to be used by as
32   * wide an audience as possible.
33   *
34   * This program is distributed in the hope that it will be useful,
35   * but WITHOUT ANY WARRANTY; without even the implied warranty of
36   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37   * GNU General Public License for more details.
38   *
39   * Contact details for copyright holder:
40   *
41   *     William Chesters <williamc At paneris.org>
42   *     http://paneris.org/~williamc
43   *     Obrechtstraat 114, 2517VX Den Haag, The Netherlands
44   */
45  
46  package org.melati.util;
47  
48  import java.io.Writer;
49  import java.io.FileWriter;
50  import java.io.File;
51  import java.io.FileReader;
52  import java.io.Reader;
53  import java.io.InputStream;
54  import java.io.OutputStream;
55  import java.io.FileInputStream;
56  import java.io.IOException;
57  import java.net.URL;
58  
59  /**
60   * IO utilities.
61   */ 
62  public final class IoUtils {
63  
64    private IoUtils() {
65      // Utility classes should not have a public or default constructor.
66      
67    }
68  
69   
70    /**
71     * Read into a byte array. 
72     * 
73     * Not sure this is really optimal.
74     * 
75     * @param i the inputStream
76     * @param estimate approximately how big
77     * @param limit will not be bigger than 
78     * @return a byte array no bigger than limit
79     * @throws IOException
80     */
81    public static byte[] slurp(InputStream i, int estimate, int limit)
82        throws IOException {
83      try {
84        byte[] b = new byte[estimate];
85        int p = 0;
86  
87        for (;;) {
88          int g = i.read(b, p, Math.min(b.length, limit) - p);
89          if (g == -1) break;
90          p += g;
91          if (p >= limit) break;
92          if (p >= b.length) {
93            byte[] c = new byte[2 * b.length];
94            System.arraycopy(b, 0, c, 0, p);
95            b = c;
96          }
97        }
98  
99        if (p == b.length)
100         return b;
101       else {
102         byte[] c = new byte[p];
103         System.arraycopy(b, 0, c, 0, p);
104         return c;
105       }
106     }
107     finally {
108       try { i.close(); } catch (Exception e) {
109         // Ignore
110         e = null; // shut PMD up
111       }
112     }
113   }
114 
115   /**
116    * Read into a byte array. 
117    * 
118    * Used in bibliomania.
119    * 
120    * @param i the inputStream
121    * @param estimate approximately how big
122    * @return a byte array no bigger than Integer.MAX_VALUE
123    * @throws IOException
124    */
125   public static byte[] slurp(InputStream i, int estimate) throws IOException {
126     return slurp(i, estimate, Integer.MAX_VALUE);
127   }
128 
129   /**
130    * Read an url into a byte array. 
131    * 
132    * Used in bibliomania.
133    * 
134    * @param url the url to read
135    * @param estimate approximately how big
136    * @return a byte array no bigger than Integer.MAX_VALUE
137    * @throws IOException
138    */
139   public static byte[] slurp(URL url, int estimate) throws IOException {
140     return slurp(url.openStream(), estimate);
141   }
142 
143   /**
144    * Read an url into a byte array, with a limit.
145    * 
146    * Used in bibliomania.
147    * 
148    * @param url the url to read
149    * @param estimate approximately how big
150    * @param max limit 
151    * @return a byte array no bigger than max
152    * @throws IOException
153    */
154   public static byte[] slurp(URL url, int estimate, int max)
155       throws IOException {
156     return slurp(url.openStream(), estimate, max);
157   }
158 
159   /**
160    * Read a file into a byte array.
161    * 
162    * Used in bibliomania.
163    * 
164    * @param f file to read
165    * @param estimate approximately how big
166    * @return a byte array no bigger than Integer.MAX_VALUE
167    * @throws IOException
168    */
169   public static byte[] slurp(File f, int estimate) throws IOException {
170     return slurp(new FileInputStream(f), estimate);
171   }
172 
173   /**
174    * Read from a Reader into a byte array.
175    * 
176    * Not used elsewhere as of 30/11/2006.
177    * 
178    * @param i Reader to read
179    * @param estimate approximately how big
180    * @param limit max size
181    * @return a byte array no bigger than limit
182    * @throws IOException
183    */
184   public static char[] slurp(Reader i, int estimate, int limit)
185       throws IOException {
186     try {
187       char[] b = new char[estimate];
188       int p = 0;
189 
190       for (;;) {
191         int g = i.read(b, p, Math.min(b.length, limit) - p);
192         if (g == -1) break;
193         p += g;
194         if (p >= limit) break;
195         if (p >= b.length) {
196           char[] c = new char[2 * b.length];
197           System.arraycopy(b, 0, c, 0, p);
198           b = c;
199         }
200       }
201 
202       if (p == b.length)
203         return b;
204       else {
205         char[] c = new char[p];
206         System.arraycopy(b, 0, c, 0, p);
207         return c;
208       }
209     }
210     finally {
211       try { i.close(); } catch (Exception e) {
212         //Ignore
213         e = null; // shut PMD up
214       }
215     }
216   }
217 
218   /**
219    * Read from a Reader into a byte array.
220    * 
221    * Used in bibliomania.
222    * 
223    * @param i Reader to read
224    * @param estimate approximately how big
225    * @return a byte array no bigger than Integer.MAX_VALUE
226    * @throws IOException
227    */
228   public static char[] slurp(Reader i, int estimate) throws IOException {
229     return slurp(i, estimate, Integer.MAX_VALUE);
230   }
231 
232   /**
233    * Read the output of a system command into a byte array.
234    * 
235    * Warning: potentially inefficient.
236    * Not used elsewhere as of 30/11/2006.
237    * 
238    * @param command the command to run
239    * @param estimate approximately how big
240    * @param limit max size
241    * @return a byte array no bigger than limit
242    * @throws IOException
243    */
244   public static byte[] slurpOutputOf_bytes(String[] command,
245                                            int estimate, int limit)
246       throws IOException {
247     Process proc = Runtime.getRuntime().exec(command);
248 
249     byte[] output = IoUtils.slurp(proc.getInputStream(), estimate, limit);
250 
251     byte[] errors = IoUtils.slurp(proc.getErrorStream(), estimate, limit);
252 
253     try {
254       if (proc.waitFor() != 0)
255         throw new ProcessFailedException(command[0] + " failed",
256                                          new String(errors));
257 
258       return output;
259     }
260     catch (InterruptedException e) {
261       throw new IOException("interrupted while waiting for " +
262                             command[0] + " to complete");
263     }
264   }
265 
266   /**
267    * Read the output of a system command into a byte array.
268    * 
269    * Warning: potentially inefficient.
270    * Not used elsewhere as of 30/11/2006.
271    * 
272    * @param command the command to run
273    * @param estimate approximately how big
274    * @param limit max size
275    * @return a String no bigger than limit
276    * @throws IOException
277    */
278   public static String slurpOutputOf(String[] command, int estimate, int limit)
279       throws IOException {
280     return new String(slurpOutputOf_bytes(command, estimate, limit));
281   }
282 
283   /**
284    * Copy from an InputStream to an OutputStream.
285    * Not used elsewhere as of 30/11/2006.
286    * 
287    * @param i the InputStream
288    * @param buf the size of buffer to use
289    * @param o the OutputStream
290    * @throws IOException
291    */
292   public static void copy(InputStream i, int buf, OutputStream o)
293       throws IOException {
294     byte b[] = new byte[buf];
295     for (;;) {
296       int g = i.read(b);
297       if (g == -1) break;
298       o.write(b, 0, g);
299     }
300   }
301 
302   /**
303    * Copy from a Reader to a Writer.
304    * Not used elsewhere as of 30/11/2006.
305    * 
306    * @param i the Reader
307    * @param buf the size of buffer to use
308    * @param o the Writer
309    * @throws IOException
310    */
311   public static void copy(Reader i, int buf, Writer o)
312       throws IOException {
313     char b[] = new char[buf];
314     for (;;) {
315       int g = i.read(b);
316       if (g == -1) break;
317       o.write(b, 0, g);
318     }
319   }
320 
321   /**
322    * Copy from one file to another.
323    * 
324    * Used in bibliomania.
325    * @param from input file
326    * @param buf the size of buffer to use
327    * @param to output file
328    * @throws IOException
329    */
330   public static void copy(File from, int buf, File to) throws IOException {
331     FileReader i = new FileReader(from);
332     try {
333       FileWriter o = new FileWriter(to);
334       try {
335         copy(i, buf, o);
336       }
337       finally {
338         try { o.close(); } catch (Exception e) {
339           //Ignore
340           e = null; // shut PMD up
341         }
342       }
343     }
344     finally {
345       try { i.close(); } catch (Exception e) {
346         //Ignore
347         e = null; // shut PMD up    
348       }
349     }
350   }
351 }
352 
353 
354 
355 
356 
357 
358 
359 
360 
361 
362 
363