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 19package org.eclipse.jetty.util; 20import java.io.ByteArrayOutputStream; 21import java.io.Closeable; 22import java.io.File; 23import java.io.FileInputStream; 24import java.io.FileOutputStream; 25import java.io.IOException; 26import java.io.InputStream; 27import java.io.InputStreamReader; 28import java.io.OutputStream; 29import java.io.PrintWriter; 30import java.io.Reader; 31import java.io.StringWriter; 32import java.io.Writer; 33 34import org.eclipse.jetty.util.log.Log; 35import org.eclipse.jetty.util.log.Logger; 36import 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 */ 43public 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 { 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 77 Job(InputStream in,OutputStream out) 78 { 79 this.in=in; 80 this.out=out; 81 this.read=null; 82 this.write=null; 83 } 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 */ 512 public static Writer getNullWriter() 513 { 514 return __nullWriter; 515 } 516 517 /* ------------------------------------------------------------ */ 518 /** 519 * @return An writer to nowhere 520 */ 521 public static PrintWriter getNullPrintWriter() 522 { 523 return __nullPrintWriter; 524 } 525 526 /* ------------------------------------------------------------ */ 527 /* ------------------------------------------------------------ */ 528 private static class NullWrite extends Writer 529 { 530 @Override 531 public void close(){} 532 @Override 533 public void flush(){} 534 @Override 535 public void write(char[]b){} 536 @Override 537 public void write(char[]b,int o,int l){} 538 @Override 539 public void write(int b){} 540 @Override 541 public void write(String s){} 542 @Override 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