001 /* 002 * JBoss DNA (http://www.jboss.org/dna) 003 * See the COPYRIGHT.txt file distributed with this work for information 004 * regarding copyright ownership. Some portions may be licensed 005 * to Red Hat, Inc. under one or more contributor license agreements. 006 * See the AUTHORS.txt file in the distribution for a full listing of 007 * individual contributors. 008 * 009 * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA 010 * is licensed to you under the terms of the GNU Lesser General Public License as 011 * published by the Free Software Foundation; either version 2.1 of 012 * the License, or (at your option) any later version. 013 * 014 * JBoss DNA is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 017 * Lesser General Public License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public 020 * License along with this software; if not, write to the Free 021 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 022 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 023 */ 024 package org.jboss.dna.common.util; 025 026 import java.io.BufferedInputStream; 027 import java.io.ByteArrayOutputStream; 028 import java.io.File; 029 import java.io.FileInputStream; 030 import java.io.FileReader; 031 import java.io.IOException; 032 import java.io.InputStream; 033 import java.io.InputStreamReader; 034 import java.io.OutputStream; 035 import java.io.Reader; 036 import java.io.Writer; 037 import java.util.Arrays; 038 039 /** 040 * @author Randall Hauch 041 */ 042 public class IoUtil { 043 044 /** 045 * Read and return the entire contents of the supplied {@link InputStream stream}. This method always closes the stream when 046 * finished reading. 047 * 048 * @param stream the stream to the contents; may be null 049 * @return the contents, or an empty byte array if the supplied reader is null 050 * @throws IOException if there is an error reading the content 051 */ 052 public static byte[] readBytes( InputStream stream ) throws IOException { 053 if (stream == null) return new byte[] {}; 054 byte[] buffer = new byte[1024]; 055 ByteArrayOutputStream output = new ByteArrayOutputStream(); 056 boolean error = false; 057 try { 058 int numRead = 0; 059 while ((numRead = stream.read(buffer)) > -1) { 060 output.write(buffer, 0, numRead); 061 } 062 } catch (IOException e) { 063 error = true; // this error should be thrown, even if there is an error closing stream 064 throw e; 065 } catch (RuntimeException e) { 066 error = true; // this error should be thrown, even if there is an error closing stream 067 throw e; 068 } finally { 069 try { 070 stream.close(); 071 } catch (IOException e) { 072 if (!error) throw e; 073 } 074 } 075 output.flush(); 076 return output.toByteArray(); 077 } 078 079 /** 080 * Read and return the entire contents of the supplied {@link File file}. 081 * 082 * @param file the file containing the contents; may be null 083 * @return the contents, or an empty byte array if the supplied file is null 084 * @throws IOException if there is an error reading the content 085 */ 086 public static byte[] readBytes( File file ) throws IOException { 087 if (file == null) return new byte[] {}; 088 InputStream stream = new BufferedInputStream(new FileInputStream(file)); 089 boolean error = false; 090 try { 091 return readBytes(stream); 092 } catch (IOException e) { 093 error = true; // this error should be thrown, even if there is an error closing stream 094 throw e; 095 } catch (RuntimeException e) { 096 error = true; // this error should be thrown, even if there is an error closing stream 097 throw e; 098 } finally { 099 try { 100 stream.close(); 101 } catch (IOException e) { 102 if (!error) throw e; 103 } 104 } 105 } 106 107 /** 108 * Read and return the entire contents of the supplied {@link Reader}. This method always closes the reader when finished 109 * reading. 110 * 111 * @param reader the reader of the contents; may be null 112 * @return the contents, or an empty string if the supplied reader is null 113 * @throws IOException if there is an error reading the content 114 */ 115 public static String read( Reader reader ) throws IOException { 116 if (reader == null) return ""; 117 StringBuilder sb = new StringBuilder(); 118 boolean error = false; 119 try { 120 int numRead = 0; 121 char[] buffer = new char[1024]; 122 while ((numRead = reader.read(buffer)) > -1) { 123 sb.append(buffer, 0, numRead); 124 } 125 } catch (IOException e) { 126 error = true; // this error should be thrown, even if there is an error closing reader 127 throw e; 128 } catch (RuntimeException e) { 129 error = true; // this error should be thrown, even if there is an error closing reader 130 throw e; 131 } finally { 132 try { 133 reader.close(); 134 } catch (IOException e) { 135 if (!error) throw e; 136 } 137 } 138 return sb.toString(); 139 } 140 141 /** 142 * Read and return the entire contents of the supplied {@link InputStream}. This method always closes the stream when finished 143 * reading. 144 * 145 * @param stream the streamed contents; may be null 146 * @return the contents, or an empty string if the supplied stream is null 147 * @throws IOException if there is an error reading the content 148 */ 149 public static String read( InputStream stream ) throws IOException { 150 return stream == null ? "" : read(new InputStreamReader(stream)); 151 } 152 153 /** 154 * Read and return the entire contents of the supplied {@link File}. 155 * 156 * @param file the file containing the information to be read; may be null 157 * @return the contents, or an empty string if the supplied reader is null 158 * @throws IOException if there is an error reading the content 159 */ 160 public static String read( File file ) throws IOException { 161 if (file == null) return ""; 162 StringBuilder sb = new StringBuilder(); 163 boolean error = false; 164 Reader reader = new FileReader(file); 165 try { 166 int numRead = 0; 167 char[] buffer = new char[1024]; 168 while ((numRead = reader.read(buffer)) > -1) { 169 sb.append(buffer, 0, numRead); 170 } 171 } catch (IOException e) { 172 error = true; // this error should be thrown, even if there is an error closing reader 173 throw e; 174 } catch (RuntimeException e) { 175 error = true; // this error should be thrown, even if there is an error closing reader 176 throw e; 177 } finally { 178 try { 179 reader.close(); 180 } catch (IOException e) { 181 if (!error) throw e; 182 } 183 } 184 return sb.toString(); 185 } 186 187 /** 188 * Write the entire contents of the supplied string to the given stream. This method always flushes and closes the stream when 189 * finished. 190 * 191 * @param content the content to write to the stream; may be null 192 * @param stream the stream to which the content is to be written 193 * @throws IOException 194 * @throws IllegalArgumentException if the stream is null 195 */ 196 public static void write( String content, 197 OutputStream stream ) throws IOException { 198 CheckArg.isNotNull(stream, "destination stream"); 199 boolean error = false; 200 try { 201 if (content != null) { 202 byte[] bytes = content.getBytes(); 203 stream.write(bytes, 0, bytes.length); 204 } 205 } catch (IOException e) { 206 error = true; // this error should be thrown, even if there is an error flushing/closing stream 207 throw e; 208 } catch (RuntimeException e) { 209 error = true; // this error should be thrown, even if there is an error flushing/closing stream 210 throw e; 211 } finally { 212 try { 213 stream.flush(); 214 } catch (IOException e) { 215 if (!error) throw e; 216 } finally { 217 try { 218 stream.close(); 219 } catch (IOException e) { 220 if (!error) throw e; 221 } 222 } 223 } 224 } 225 226 /** 227 * Write the entire contents of the supplied string to the given writer. This method always flushes and closes the writer when 228 * finished. 229 * 230 * @param content the content to write to the writer; may be null 231 * @param writer the writer to which the content is to be written 232 * @throws IOException 233 * @throws IllegalArgumentException if the writer is null 234 */ 235 public static void write( String content, 236 Writer writer ) throws IOException { 237 CheckArg.isNotNull(writer, "destination writer"); 238 boolean error = false; 239 try { 240 if (content != null) { 241 writer.write(content); 242 } 243 } catch (IOException e) { 244 error = true; // this error should be thrown, even if there is an error flushing/closing writer 245 throw e; 246 } catch (RuntimeException e) { 247 error = true; // this error should be thrown, even if there is an error flushing/closing writer 248 throw e; 249 } finally { 250 try { 251 writer.flush(); 252 } catch (IOException e) { 253 if (!error) throw e; 254 } finally { 255 try { 256 writer.close(); 257 } catch (IOException e) { 258 if (!error) throw e; 259 } 260 } 261 } 262 } 263 264 /** 265 * Write the entire contents of the supplied string to the given stream. This method always flushes and closes the stream when 266 * finished. 267 * 268 * @param input the content to write to the stream; may be null 269 * @param stream the stream to which the content is to be written 270 * @throws IOException 271 * @throws IllegalArgumentException if the stream is null 272 */ 273 public static void write( InputStream input, 274 OutputStream stream ) throws IOException { 275 CheckArg.isNotNull(stream, "destination stream"); 276 boolean error = false; 277 try { 278 if (input != null) { 279 byte[] buffer = new byte[1024]; 280 try { 281 int numRead = 0; 282 while ((numRead = input.read(buffer)) > -1) { 283 stream.write(buffer, 0, numRead); 284 } 285 } finally { 286 input.close(); 287 } 288 } 289 } catch (IOException e) { 290 error = true; // this error should be thrown, even if there is an error flushing/closing stream 291 throw e; 292 } catch (RuntimeException e) { 293 error = true; // this error should be thrown, even if there is an error flushing/closing stream 294 throw e; 295 } finally { 296 try { 297 stream.flush(); 298 } catch (IOException e) { 299 if (!error) throw e; 300 } finally { 301 try { 302 stream.close(); 303 } catch (IOException e) { 304 if (!error) throw e; 305 } 306 } 307 } 308 } 309 310 /** 311 * Write the entire contents of the supplied string to the given writer. This method always flushes and closes the writer when 312 * finished. 313 * 314 * @param input the content to write to the writer; may be null 315 * @param writer the writer to which the content is to be written 316 * @throws IOException 317 * @throws IllegalArgumentException if the writer is null 318 */ 319 public static void write( Reader input, 320 Writer writer ) throws IOException { 321 CheckArg.isNotNull(writer, "destination writer"); 322 boolean error = false; 323 try { 324 if (input != null) { 325 char[] buffer = new char[1024]; 326 try { 327 int numRead = 0; 328 while ((numRead = input.read(buffer)) > -1) { 329 writer.write(buffer, 0, numRead); 330 } 331 } finally { 332 input.close(); 333 } 334 } 335 } catch (IOException e) { 336 error = true; // this error should be thrown, even if there is an error flushing/closing writer 337 throw e; 338 } catch (RuntimeException e) { 339 error = true; // this error should be thrown, even if there is an error flushing/closing writer 340 throw e; 341 } finally { 342 try { 343 writer.flush(); 344 } catch (IOException e) { 345 if (!error) throw e; 346 } finally { 347 try { 348 writer.close(); 349 } catch (IOException e) { 350 if (!error) throw e; 351 } 352 } 353 } 354 } 355 356 /** 357 * Write the entire contents of the supplied string to the given stream. This method always flushes and closes the stream when 358 * finished. 359 * 360 * @param input1 the first stream 361 * @param input2 the second stream 362 * @return true if the streams contain the same content, or false otherwise 363 * @throws IOException 364 * @throws IllegalArgumentException if the stream is null 365 */ 366 public static boolean isSame( InputStream input1, 367 InputStream input2 ) throws IOException { 368 CheckArg.isNotNull(input1, "input1"); 369 CheckArg.isNotNull(input2, "input2"); 370 boolean error = false; 371 try { 372 byte[] buffer1 = new byte[1024]; 373 byte[] buffer2 = new byte[1024]; 374 try { 375 int numRead1 = 0; 376 int numRead2 = 0; 377 while (true) { 378 numRead1 = input1.read(buffer1); 379 numRead2 = input2.read(buffer2); 380 if (numRead1 > -1) { 381 if (numRead2 != numRead1) return false; 382 // Otherwise same number of bytes read 383 if (!Arrays.equals(buffer1, buffer2)) return false; 384 // Otherwise same bytes read, so continue ... 385 } else { 386 // Nothing more in stream 1 ... 387 return numRead2 < 0; 388 } 389 } 390 } finally { 391 input1.close(); 392 } 393 } catch (IOException e) { 394 error = true; // this error should be thrown, even if there is an error closing stream 2 395 throw e; 396 } catch (RuntimeException e) { 397 error = true; // this error should be thrown, even if there is an error closing stream 2 398 throw e; 399 } finally { 400 try { 401 input2.close(); 402 } catch (IOException e) { 403 if (!error) throw e; 404 } 405 } 406 } 407 408 private IoUtil() { 409 // Prevent construction 410 } 411 }