001/** 002 * Copyright (c) 2014, the Railo Company Ltd. 003 * Copyright (c) 2016, Lucee Assosication Switzerland 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.commons.io; 020 021import java.io.BufferedInputStream; 022import java.io.BufferedOutputStream; 023import java.io.BufferedReader; 024import java.io.BufferedWriter; 025import java.io.ByteArrayInputStream; 026import java.io.ByteArrayOutputStream; 027import java.io.Closeable; 028import java.io.File; 029import java.io.FileInputStream; 030import java.io.FileNotFoundException; 031import java.io.FileOutputStream; 032import java.io.IOException; 033import java.io.InputStream; 034import java.io.InputStreamReader; 035import java.io.OutputStream; 036import java.io.OutputStreamWriter; 037import java.io.PrintStream; 038import java.io.Reader; 039import java.io.StringWriter; 040import java.io.UnsupportedEncodingException; 041import java.io.Writer; 042import java.lang.reflect.Method; 043import java.nio.charset.Charset; 044import java.sql.Connection; 045import java.sql.ResultSet; 046import java.util.LinkedList; 047import java.util.zip.ZipFile; 048 049import javax.mail.Transport; 050 051import org.apache.http.client.methods.HttpRequestBase; 052import org.apache.http.impl.client.CloseableHttpClient; 053import org.apache.http.protocol.HttpContext; 054 055import lucee.print; 056import lucee.commons.io.res.Resource; 057import lucee.commons.lang.ExceptionUtil; 058import lucee.commons.lang.StringUtil; 059import lucee.commons.net.URLEncoder; 060import lucee.commons.net.http.httpclient4.HTTPResponse4Impl; 061import lucee.runtime.PageContext; 062import lucee.runtime.engine.ThreadLocalPageContext; 063import lucee.runtime.exp.PageException; 064import lucee.runtime.op.Caster; 065import lucee.runtime.tag.Http41; 066import net.sf.jmimemagic.Magic; 067import net.sf.jmimemagic.MagicMatch; 068 069import com.lowagie.text.Document; 070 071/** 072 * I/O Util 073 */ 074public final class IOUtil { 075 076 /** 077 * copy a inputstream to a outputstream 078 * @param in 079 * @param out 080 * @param closeIS 081 * @param closeOS 082 * @throws IOException 083 */ 084 public static final void copy(InputStream in, OutputStream out, boolean closeIS, boolean closeOS) throws IOException { 085 try { 086 copy(in,out,0xffff); 087 } 088 finally { 089 if(closeIS)closeEL(in); 090 if(closeOS)closeEL(out); 091 } 092 } 093 094 /** 095 * copy a inputstream to a outputstream 096 * @param in 097 * @param out 098 * @param closeIS 099 * @param closeOS 100 * @throws IOException 101 */ 102 public static final void merge(InputStream in1, InputStream in2, OutputStream out, boolean closeIS1, boolean closeIS2, boolean closeOS) throws IOException { 103 try { 104 merge(in1,in2,out,0xffff); 105 } 106 finally { 107 if(closeIS1)closeEL(in1); 108 if(closeIS2)closeEL(in2); 109 if(closeOS)closeEL(out); 110 } 111 } 112 113 /** 114 * copy a inputstream to a outputstream 115 * @param in 116 * @param out 117 * @param closeIS 118 * @param closeOS 119 * @throws IOException 120 */ 121 public static final void copy(OutputStream out, InputStream in,boolean closeIS, boolean closeOS) throws IOException { 122 copy(in,out,closeIS,closeOS); 123 } 124 125 /** 126 * copy a input resource to a output resource 127 * @param in 128 * @param out 129 * @throws IOException 130 */ 131 public static void copy(Resource in, Resource out) throws IOException { 132 in.copyTo(out, false); 133 } 134 135 public static void merge(Resource in1, Resource in2, Resource out) throws IOException { 136 InputStream is1=null; 137 InputStream is2=null; 138 OutputStream os=null; 139 try { 140 is1=toBufferedInputStream(in1.getInputStream()); 141 is2=toBufferedInputStream(in2.getInputStream()); 142 os=toBufferedOutputStream(out.getOutputStream()); 143 } 144 catch(IOException ioe) { 145 IOUtil.closeEL(is1); 146 IOUtil.closeEL(is2); 147 IOUtil.closeEL(os); 148 throw ioe; 149 } 150 merge(is1,is2,os,true,true,true); 151 } 152 153 /** 154 * copy a input resource to a output resource 155 * @param in 156 * @param out 157 * @throws IOException 158 */ 159 public static void copy(InputStream is, Resource out, boolean closeIS) throws IOException { 160 OutputStream os=null; 161 try { 162 os=toBufferedOutputStream(out.getOutputStream()); 163 } 164 catch(IOException ioe) { 165 IOUtil.closeEL(os); 166 throw ioe; 167 } 168 copy(is,os,closeIS,true); 169 } 170 171 /** 172 * copy a input resource to a output resource 173 * @param in 174 * @param out 175 * @throws IOException 176 */ 177 public static void copy(Resource in, OutputStream os, boolean closeOS) throws IOException { 178 InputStream is=null; 179 try { 180 is=toBufferedInputStream(in.getInputStream()); 181 } 182 catch(IOException ioe) { 183 IOUtil.closeEL(is); 184 throw ioe; 185 } 186 copy(is,os,true,closeOS); 187 } 188 189 public static final void copy(InputStream in, OutputStream out, int offset, int length) throws IOException { 190 copy(in, out, offset, length,0xffff); 191 } 192 193 public static final void copy(InputStream in, OutputStream out, long offset, long length) throws IOException { 194 int len; 195 byte[] buffer; 196 int block=0xffff; 197 198 // first offset to start 199 if(offset>0) { 200 long skipped=0; 201 try{ 202 skipped = in.skip(offset); 203 } 204 catch(Throwable t){ 205 ExceptionUtil.rethrowIfNecessary(t); 206 } 207 208 if(skipped<=0) { 209 while(true) { 210 if(block>offset)block=(int)offset; 211 buffer = new byte[block]; 212 len = in.read(buffer); 213 if(len==-1) throw new IOException("reading offset is bigger than input itself"); 214 //dnos.write(buffer, 0, len); 215 offset-=len; 216 if(offset<=0) break; 217 } 218 } 219 } 220 221 // write part 222 if(length<0) { 223 copy(in, out,block); 224 return; 225 } 226 227 while(true) { 228 if(block>length)block=(int) length; 229 buffer = new byte[block]; 230 len = in.read(buffer); 231 if(len==-1) break; 232 out.write(buffer, 0, len); 233 length-=len; 234 if(length<=0) break; 235 } 236 } 237 238 public static final void copy(InputStream in, OutputStream out, int offset, int length, int blockSize) throws IOException { 239 240 int len; 241 byte[] buffer; 242 int block;//0xffff; 243 244 // first offset to start 245 if(offset>0) { 246 long skipped=0; 247 try{ 248 skipped = in.skip(offset); 249 } 250 catch(Throwable t){ 251 ExceptionUtil.rethrowIfNecessary(t); 252 } 253 254 if(skipped<=0) { 255 block = blockSize;//0xffff; 256 while(true) { 257 if(block>offset)block=offset; 258 buffer = new byte[block]; 259 len = in.read(buffer); 260 if(len==-1) throw new IOException("reading offset is bigger than input itself"); 261 //dnos.write(buffer, 0, len); 262 offset-=len; 263 if(offset<=0) break; 264 } 265 } 266 } 267 268 // write part 269 if(length<0) { 270 copy(in, out,blockSize); 271 return; 272 } 273 block = blockSize;//0xffff; 274 while(true) { 275 if(block>length)block=length; 276 buffer = new byte[block]; 277 len = in.read(buffer); 278 if(len==-1) break; 279 out.write(buffer, 0, len); 280 length-=len; 281 if(length<=0) break; 282 } 283 } 284 285 /** 286 * copy a inputstream to a outputstream 287 * @param in 288 * @param out 289 * @param blockSize 290 * @throws IOException 291 */ 292 private static final void copy(InputStream in, OutputStream out, int blockSize) throws IOException { 293 byte[] buffer = new byte[blockSize]; 294 int len; 295 while((len = in.read(buffer)) !=-1) { 296 out.write(buffer, 0, len); 297 } 298 } 299 300 private static final void merge(InputStream in1, InputStream in2, OutputStream out, int blockSize) throws IOException { 301 copy(in1, out,blockSize); 302 copy(in2, out,blockSize); 303 } 304 305 /** 306 * copy a reader to a writer 307 * @param r 308 * @param w 309 * @throws IOException 310 */ 311 private static final void copy(Reader r, Writer w, long timeout) throws IOException { 312 copy(r,w,0xffff,timeout); 313 } 314 315 /** 316 * copy a reader to a writer 317 * @param reader 318 * @param writer 319 * @param closeReader 320 * @param closeWriter 321 * @throws IOException 322 */ 323 public static final void copy(Reader reader, Writer writer, boolean closeReader, boolean closeWriter) throws IOException { 324 try { 325 copy(reader,writer,0xffff,-1); 326 } 327 finally { 328 if(closeReader)closeEL(reader); 329 if(closeWriter)closeEL(writer); 330 } 331 } 332 333 /** 334 * copy a reader to a writer 335 * @param r 336 * @param w 337 * @param blockSize 338 * @throws IOException 339 */ 340 private static final void copy(Reader r, Writer w, int blockSize, long timeout) throws IOException { 341 if(timeout<1) { 342 char[] buffer = new char[blockSize]; 343 int len; 344 345 while((len = r.read(buffer)) !=-1) 346 w.write(buffer, 0, len); 347 } 348 else { 349 Copy c=new Copy(r, w, blockSize, timeout); 350 c.start(); 351 352 try { 353 synchronized(c.notifier){//print.err(timeout); 354 c.notifier.wait(timeout+1); 355 } 356 } 357 catch (InterruptedException ie) { 358 throw ExceptionUtil.toIOException(c.t); 359 } 360 if(c.t!=null) throw ExceptionUtil.toIOException(c.t); 361 if(!c.finished) throw new IOException("reached timeout ("+timeout+"ms) while copying data"); 362 363 } 364 } 365 366 /** 367 * copy content of in file to out File 368 * @param in input 369 * @param out output 370 * @throws IOException 371 */ 372 public void copy(File in,File out) throws IOException { 373 InputStream is=null; 374 OutputStream os=null; 375 try { 376 is = new BufferedFileInputStream(in); 377 os = new BufferedFileOutputStream(out); 378 } 379 catch (IOException ioe) { 380 closeEL(is,os); 381 throw ioe; 382 } 383 copy(is,os,true,true); 384 } 385 386 387 388 389 390 /** 391 * close inputstream without a Exception 392 * @param is 393 * @param os 394 */ 395 public static void closeEL(InputStream is, OutputStream os) { 396 closeEL(is); 397 closeEL(os); 398 } 399 400 /** 401 * close inputstream without a Exception 402 * @param is 403 */ 404 public static void closeEL(InputStream is) { 405 try { 406 if(is!=null)is.close(); 407 } 408 //catch (AlwaysThrow at) {throw at;} 409 catch (Throwable t) { 410 ExceptionUtil.rethrowIfNecessary(t); 411 } 412 } 413 414 public static void closeEL(ZipFile zip) { 415 try { 416 if(zip!=null)zip.close(); 417 } 418 //catch (AlwaysThrow at) {throw at;} 419 catch (Throwable t) { 420 ExceptionUtil.rethrowIfNecessary(t); 421 } 422 } 423 424 /** 425 * close outputstream without a Exception 426 * @param os 427 */ 428 public static void closeEL(OutputStream os) { 429 try { 430 if(os!=null)os.close(); 431 } 432 //catch (AlwaysThrow at) {throw at;} 433 catch (Throwable t) { 434 ExceptionUtil.rethrowIfNecessary(t); 435 } 436 } 437 438 public static void closeEL(ResultSet rs) { 439 try { 440 if(rs!=null)rs.close(); 441 } 442 catch (Throwable t) { 443 ExceptionUtil.rethrowIfNecessary(t); 444 } 445 } 446 447 /** 448 * close Reader without a Exception 449 * @param r 450 */ 451 public static void closeEL(Reader r) { 452 try { 453 if(r!=null)r.close(); 454 } 455 //catch (AlwaysThrow at) {throw at;} 456 catch (Throwable t) { 457 ExceptionUtil.rethrowIfNecessary(t); 458 } 459 } 460 461 462 /** 463 * close Closeable without a Exception 464 * @param r 465 */ 466 public static void closeEL(Closeable c ) { 467 try { 468 if(c!=null)c.close(); 469 } 470 //catch (AlwaysThrow at) {throw at;} 471 catch (Throwable t) { 472 ExceptionUtil.rethrowIfNecessary(t); 473 } 474 } 475 476 /** 477 * close Writer without a Exception 478 * @param w 479 */ 480 public static void closeEL(Writer w) { 481 try { 482 if(w!=null)w.close(); 483 } 484 //catch (AlwaysThrow at) {throw at;} 485 catch (Throwable t) { 486 ExceptionUtil.rethrowIfNecessary(t); 487 } 488 } 489 490 /** 491 * close Writer without a Exception 492 * @param w 493 */ 494 public static void closeEL(Transport t) { 495 try { 496 if(t!=null && t.isConnected())t.close(); 497 } 498 catch (Throwable e) { 499 ExceptionUtil.rethrowIfNecessary(e); 500 } 501 } 502 503 504 public static void closeEL(Document doc) { 505 try { 506 if(doc!=null)doc.close(); 507 } 508 catch (Throwable t) { 509 ExceptionUtil.rethrowIfNecessary(t); 510 } 511 } 512 513 public static void closeEL(Connection conn) { 514 try { 515 if(conn!=null)conn.close(); 516 } 517 catch (Throwable t) { 518 ExceptionUtil.rethrowIfNecessary(t); 519 } 520 } 521 522 523 524 /** 525 * call close method from any Object with a close method. 526 * @param obj 527 */ 528 public static void closeEL(Object obj) { 529 if(obj instanceof InputStream) IOUtil.closeEL((InputStream)obj); 530 else if(obj instanceof OutputStream) IOUtil.closeEL((OutputStream)obj); 531 else if(obj instanceof Writer) IOUtil.closeEL((Writer)obj); 532 else if(obj instanceof Reader) IOUtil.closeEL((Reader)obj); 533 else if(obj instanceof Closeable) IOUtil.closeEL((Closeable)obj); 534 else if(obj instanceof ZipFile) IOUtil.closeEL((ZipFile)obj); 535 else if(obj instanceof ResultSet) IOUtil.closeEL((ResultSet)obj); 536 else { 537 try { 538 Method method = obj.getClass().getMethod("close",new Class[0]); 539 method.invoke(obj,new Object[0]); 540 } 541 catch (Throwable t) { 542 ExceptionUtil.rethrowIfNecessary(t); 543 } 544 } 545 } 546 547 /** 548 * @deprecated use instead <code>{@link #getReader(Resource, Charset)}</code> 549 * @param res 550 * @param charset 551 * @return 552 * @throws IOException 553 */ 554 public static Reader getReader(Resource res, String charset) throws IOException { 555 return getReader(res, CharsetUtil.toCharset(charset)); 556 } 557 558 public static Reader getReader(Resource res, Charset charset) throws IOException { 559 /* 560 00 00 FE FF UTF-32, big-endian 561 FF FE 00 00 UTF-32, little-endian 562 */ 563 564 565 InputStream is=null; 566 try { 567 is = res.getInputStream(); 568 boolean markSupported=is.markSupported(); 569 if(markSupported) is.mark(4); 570 int first = is.read(); 571 int second = is.read(); 572 // FE FF UTF-16, big-endian 573 if (first == 0xFE && second == 0xFF) { 574 return _getReader(is, CharsetUtil.UTF16BE); 575 } 576 // FF FE UTF-16, little-endian 577 if (first == 0xFF && second == 0xFE) { 578 return _getReader(is, CharsetUtil.UTF16LE); 579 } 580 581 int third=is.read(); 582 // EF BB BF UTF-8 583 if (first == 0xEF && second == 0xBB && third == 0xBF) { 584 //is.reset(); 585 return _getReader(is,CharsetUtil.UTF8); 586 } 587 /* 588 int forth=is.read(); 589 // 00 00 FE FF UTF-32, big-endian 590 if (first == 0x00 && second == 0x00 && third == 0xFE && forth == 0xFF) { 591 is.reset(); 592 return _getReader(is, "utf-32"); 593 } 594 // FF FE 00 00 UTF-32, little-endian 595 if (first == 0xFF && second == 0xFE && third == 0x00 && forth == 0x00) { 596 is.reset(); 597 return _getReader(is, "utf-32"); 598 }*/ 599 600 if(markSupported) { 601 is.reset(); 602 return _getReader(is,charset); 603 } 604 } 605 catch(IOException ioe) { 606 IOUtil.closeEL(is); 607 throw ioe; 608 } 609 610 // when mark not supported return new reader 611 closeEL(is); 612 is=null; 613 try { 614 is=res.getInputStream(); 615 } 616 catch(IOException ioe) { 617 closeEL(is); 618 throw ioe; 619 } 620 return _getReader(is, charset); 621 } 622 623 public static Reader getReader(InputStream is, Charset charset) throws IOException { 624 625 boolean markSupported=is.markSupported(); 626 if(!markSupported) return _getReader(is, charset); 627 628 if(markSupported) is.mark(4); 629 630 int first = is.read(); 631 int second = is.read(); 632 // FE FF UTF-16, big-endian 633 if (first == 0xFE && second == 0xFF) { 634 //is.reset(); 635 return _getReader(is, CharsetUtil.UTF16BE); 636 } 637 // FF FE UTF-16, little-endian 638 if (first == 0xFF && second == 0xFE) { 639 // TODO FF FE 00 00 UTF-32 little-endian 640 return _getReader(is, CharsetUtil.UTF16LE); 641 } 642 643 int third=is.read(); 644 // EF BB BF UTF-8 645 if (first == 0xEF && second == 0xBB && third == 0xBF) { 646 return _getReader(is, CharsetUtil.UTF8); 647 } 648 649 // 00 00 FE FF UTF-32 big-endian 650 int forth=is.read(); 651 if (first == 0x00 && second == 0x00 && third == 0xFE && forth == 0xFF) { 652 return _getReader(is, CharsetUtil.UTF32BE); 653 } 654 655 656 is.reset(); 657 return _getReader(is,charset); 658 } 659 660 /** 661 * @deprecated use instead <code>{@link #getReader(InputStream, Charset)}</code> 662 * @param is 663 * @param charset 664 * @return 665 * @throws IOException 666 */ 667 public static Reader getReader(InputStream is, String charset) throws IOException { 668 return getReader(is, CharsetUtil.toCharset(charset)); 669 } 670 671 /** 672 * returns a Reader for the given InputStream 673 * @param is 674 * @param charset 675 * @return Reader 676 * @throws IOException 677 */ 678 private static Reader _getReader(InputStream is, Charset charset) throws IOException { 679 if(charset==null) charset=SystemUtil.getCharset(); 680 return new BufferedReader(new InputStreamReader(is,charset)); 681 } 682 683 /** 684 * @deprecated use instead <code>{@link #toString(InputStream, Charset)}</code> 685 * @param is 686 * @param charset 687 * @return 688 * @throws IOException 689 */ 690 public static String toString(InputStream is, String charset) throws IOException { 691 return toString(is,CharsetUtil.toCharset(charset)); 692 } 693 694 /** 695 * reads string data from a InputStream 696 * @param is 697 * @param charset 698 * @return string from inputstream 699 * @throws IOException 700 */ 701 public static String toString(InputStream is, Charset charset) throws IOException { 702 return toString(getReader(is,charset)); 703 } 704 705 /** 706 * reads string data from a InputStream 707 * @param is 708 * @param charset 709 * @param timeout in milliseconds 710 * @return string from inputstream 711 * @throws IOException 712 */ 713 public static String toString(InputStream is, Charset charset, long timeout) throws IOException { 714 return toString(getReader(is,charset),timeout); 715 } 716 717 /** 718 * @deprecated use instead <code>{@link #toString(byte[], Charset)}</code> 719 * @param barr 720 * @param charset 721 * @return 722 * @throws IOException 723 */ 724 public static String toString(byte[] barr, String charset) throws IOException { 725 return toString(barr,CharsetUtil.toCharset(charset)); 726 } 727 728 public static String toString(byte[] barr, Charset charset) throws IOException { 729 return toString(getReader(new ByteArrayInputStream(barr),charset)); 730 } 731 732 733 /** 734 * reads String data from a Reader 735 * @param reader 736 * @return readed string 737 * @throws IOException 738 */ 739 public static String toString(Reader reader) throws IOException { 740 return toString(reader,-1); 741 } 742 743 /** 744 * reads String data from a Reader 745 * @param reader 746 * @param timeout timeout in milliseconds 747 * @return readed string 748 * @throws IOException 749 */ 750 public static String toString(Reader reader, long timeout) throws IOException { 751 StringWriter sw=new StringWriter(512); 752 copy(toBufferedReader(reader),sw,timeout); 753 sw.close(); 754 return sw.toString(); 755 } 756 757 /** 758 * reads String data from a Reader 759 * @param reader 760 * @return readed string 761 * @throws IOException 762 */ 763 public static String toString(Reader reader,boolean buffered) throws IOException { 764 StringWriter sw=new StringWriter(512); 765 if(buffered)copy(toBufferedReader(reader),sw,-1); 766 else copy(reader,sw,-1); 767 sw.close(); 768 return sw.toString(); 769 } 770 771 /** 772 * @deprecated use instead <code>{@link #toString(Resource, Charset)}</code> 773 * @param file 774 * @param charset 775 * @return 776 * @throws IOException 777 */ 778 public static String toString(Resource file, String charset) throws IOException { 779 return toString(file, CharsetUtil.toCharset(charset)); 780 } 781 782 /** 783 * reads String data from File 784 * @param file 785 * @param charset 786 * @return readed string 787 * @throws IOException 788 */ 789 public static String toString(Resource file, Charset charset) throws IOException { 790 Reader r = null; 791 try { 792 r = getReader(file,charset); 793 String str = toString(r); 794 return str; 795 } 796 finally { 797 closeEL(r); 798 } 799 } 800 801 /** 802 * @param reader Reader to get content from it 803 * @return returns the content of the file as String Array (Line by Line) 804 * @throws IOException 805 */ 806 public static String[] toStringArray(Reader reader) throws IOException { 807 if(reader==null)return new String[0]; 808 BufferedReader br = new BufferedReader(reader); 809 LinkedList<String> list=new LinkedList<String>(); 810 811 String line; 812 while((line=br.readLine())!=null) { 813 list.add(line); 814 } 815 br.close(); 816 String[] content=new String[list.size()]; 817 int count=0; 818 while(!list.isEmpty()) { 819 content[count++]=list.removeFirst(); 820 } 821 return content; 822 } 823 824 /** 825 * @deprecated use instead <code>{@link #write(Resource, String, Charset, boolean)}</code> 826 * writes a String to a object 827 * @param file 828 * @param string String to write to file 829 * @param charset 830 * @param append append to cuuretn data or overwrite existing data 831 * @throws IOException 832 */ 833 public static void write(File file, String string, String strCharset, boolean append) throws IOException { 834 Charset charset; 835 if(StringUtil.isEmpty(strCharset)) { 836 charset=SystemUtil.getCharset(); 837 } 838 else charset=CharsetUtil.toCharset(strCharset); 839 840 OutputStreamWriter writer=null; 841 try { 842 writer=new OutputStreamWriter(new BufferedFileOutputStream(file,append),charset); 843 writer.write(string); 844 845 } 846 finally { 847 closeEL(writer); 848 } 849 } 850 851 /** 852 * @deprecated use instead <code>{@link #write(Resource, String, Charset, boolean)}</code> 853 * @param res 854 * @param string 855 * @param charset 856 * @param append 857 * @throws IOException 858 */ 859 public static void write(Resource res, String string, String charset, boolean append) throws IOException { 860 write(res, string, CharsetUtil.toCharset(charset), append); 861 } 862 863 public static void write(Resource res, String string, Charset charset, boolean append) throws IOException { 864 if(charset==null) { 865 charset=SystemUtil.getCharset(); 866 } 867 868 869 Writer writer=null; 870 try { 871 writer=getWriter(res, charset,append); 872 writer.write(string); 873 } 874 finally { 875 closeEL(writer); 876 } 877 } 878 879 880 public static void write(Resource res, byte[] barr) throws IOException { 881 ByteArrayInputStream bais = new ByteArrayInputStream(barr); 882 OutputStream os=IOUtil.toBufferedOutputStream(res.getOutputStream()); 883 IOUtil.copy(bais, os, true, true); 884 } 885 886 public static void write(Resource res, byte[] barr, boolean append) throws IOException { 887 ByteArrayInputStream bais = new ByteArrayInputStream(barr); 888 OutputStream os=IOUtil.toBufferedOutputStream(res.getOutputStream(append)); 889 IOUtil.copy(bais, os, true, true); 890 } 891 892 /** 893 * @deprecated use instead <code>{@link #toBytes(Resource)}</code> 894 * @param file 895 * @return returns the Content of the file as byte array 896 * @throws IOException 897 */ 898 public static byte[] toBytes(File file) throws IOException { 899 BufferedFileInputStream bfis = null; 900 try { 901 bfis = new BufferedFileInputStream(file); 902 byte[] barr = toBytes(bfis); 903 return barr; 904 } 905 finally { 906 closeEL(bfis); 907 } 908 } 909 910 /** 911 * @param res 912 * @return returns the Content of the file as byte array 913 * @throws IOException 914 */ 915 public static byte[] toBytes(Resource res) throws IOException { 916 BufferedInputStream bfis = null; 917 try { 918 bfis = toBufferedInputStream(res.getInputStream()); 919 byte[] barr = toBytes(bfis); 920 return barr; 921 } 922 finally { 923 closeEL(bfis); 924 } 925 } 926 927 public static BufferedInputStream toBufferedInputStream(InputStream is) { 928 if(is instanceof BufferedInputStream) return (BufferedInputStream) is; 929 return new BufferedInputStream(is); 930 } 931 932 public static BufferedOutputStream toBufferedOutputStream(OutputStream os) { 933 if(os instanceof BufferedOutputStream) return (BufferedOutputStream) os; 934 return new BufferedOutputStream(os); 935 } 936 937 public static BufferedReader toBufferedReader(Reader r) { 938 if(r instanceof BufferedReader) return (BufferedReader) r; 939 return new BufferedReader(r); 940 } 941 942 /** 943 * @deprecated use instead <code>{@link #getBufferedReader(Resource, Charset)}</code> 944 * @param res 945 * @param charset 946 * @return 947 * @throws IOException 948 */ 949 public static BufferedReader getBufferedReader(Resource res,String charset) throws IOException { 950 return getBufferedReader(res,CharsetUtil.toCharset(charset)); 951 } 952 953 public static BufferedReader getBufferedReader(Resource res,Charset charset) throws IOException { 954 return toBufferedReader(getReader(res, charset)); 955 } 956 957 958 public static BufferedWriter toBufferedWriter(Writer w) { 959 if(w instanceof BufferedWriter) return (BufferedWriter) w; 960 return new BufferedWriter(w); 961 } 962 963 /** 964 * @param is 965 * @return returns the Content of the file as byte array 966 * @throws IOException 967 */ 968 public static byte[] toBytes(InputStream is) throws IOException { 969 return toBytes(is,false); 970 } 971 972 973 public static byte[] toBytes(InputStream is, boolean closeStream) throws IOException { 974 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 975 copy(is,baos,closeStream,true); 976 return baos.toByteArray(); 977 } 978 979 public static byte[] toBytesMax(InputStream is, int max) throws IOException { 980 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 981 copy(is,baos,0,max); 982 return baos.toByteArray(); 983 } 984 985 /** 986 * flush OutputStream without a Exception 987 * @param os 988 */ 989 public static void flushEL(OutputStream os) { 990 try { 991 if(os!=null)os.flush(); 992 } catch (Exception e) {} 993 } 994 995 /** 996 * flush OutputStream without a Exception 997 * @param os 998 */ 999 public static void flushEL(Writer w) { 1000 try { 1001 if(w!=null)w.flush(); 1002 } catch (Exception e) {} 1003 } 1004 1005 /** 1006 * check if given encoding is ok 1007 * @param encoding 1008 * @throws PageException 1009 */ 1010 public static void checkEncoding(String encoding) throws IOException { 1011 try { 1012 URLEncoder.encode("", encoding); 1013 } catch (UnsupportedEncodingException e) { 1014 throw new IOException("invalid encoding ["+encoding+"]"); 1015 } 1016 } 1017 1018 /** 1019 * return the mime type of a file, dont check extension 1020 * @param barr 1021 * @param defaultValue 1022 * @return mime type of the file 1023 */ 1024 public static String getMimeType(InputStream is, String defaultValue) { 1025 try { 1026 return getMimeType(IOUtil.toBytesMax(is,1000), defaultValue); 1027 } catch (IOException e) { 1028 return defaultValue; 1029 } 1030 1031 1032 /*try { 1033 return URLConnection.guessContentTypeFromStream(is); 1034 } catch (Throwable t) { 1035 ExceptionUtil.rethrowIfNecessary(t); 1036 return defaultValue; 1037 }*/ 1038 1039 /*try { 1040 return getMimeType(IOUtil.toBytesMax(is,1000), defaultValue); 1041 } catch (IOException e) { 1042 return defaultValue; 1043 }*/ 1044 } 1045 1046 1047 /** 1048 * return the mime type of a file, dont check extension 1049 * @param barr 1050 * @return mime type of the file 1051 * @throws IOException 1052 */ 1053 public static String getMimeType(byte[] barr, String defaultValue) { 1054 1055 //String mt = getMimeType(new ByteArrayInputStream(barr), null); 1056 //if(!StringUtil.isEmpty(mt,true)) return mt; 1057 1058 PrintStream out = System.out; 1059 try { 1060 System.setOut(new PrintStream(DevNullOutputStream.DEV_NULL_OUTPUT_STREAM)); 1061 MagicMatch match = Magic.getMagicMatch(barr); 1062 return match.getMimeType(); 1063 } 1064 catch (Throwable t) { 1065 ExceptionUtil.rethrowIfNecessary(t); 1066 return defaultValue; 1067 } 1068 finally { 1069 System.setOut(out); 1070 } 1071 } 1072 1073 /** 1074 * @deprecated use instead <code>{@link #getWriter(Resource, Charset)}</code> 1075 * @param res 1076 * @param charset 1077 * @return 1078 * @throws IOException 1079 */ 1080 public static Writer getWriter(Resource res, String charset) throws IOException { 1081 return getWriter(res, CharsetUtil.toCharset(charset)); 1082 } 1083 1084 public static Writer getWriter(Resource res, Charset charset) throws IOException { 1085 OutputStream os=null; 1086 try { 1087 os=res.getOutputStream(); 1088 } 1089 catch(IOException ioe) { 1090 closeEL(os); 1091 throw ioe; 1092 } 1093 return getWriter(os, charset); 1094 1095 } 1096 1097 /** 1098 * @deprecated use instead <code>{@link #getWriter(Resource, Charset,boolean)}</code> 1099 * @param res 1100 * @param charset 1101 * @param append 1102 * @return 1103 * @throws IOException 1104 */ 1105 public static Writer getWriter(Resource res, String charset, boolean append) throws IOException { 1106 return getWriter(res, CharsetUtil.toCharset(charset), append); 1107 } 1108 1109 public static Writer getWriter(Resource res, Charset charset, boolean append) throws IOException { 1110 OutputStream os=null; 1111 try { 1112 os=res.getOutputStream(append); 1113 } 1114 catch(IOException ioe) { 1115 closeEL(os); 1116 throw ioe; 1117 } 1118 return getWriter(os, charset); 1119 } 1120 1121 /** 1122 * @deprecated use instead <code>{@link #getWriter(Resource, Charset)}</code> 1123 * returns a Reader for the given File and charset (Automaticly check BOM Files) 1124 * @param file 1125 * @param charset 1126 * @return Reader 1127 * @throws IOException 1128 */ 1129 public static Writer getWriter(File file, String charset) throws IOException { 1130 OutputStream os=null; 1131 try { 1132 os=new FileOutputStream(file); 1133 } 1134 catch(IOException ioe) { 1135 closeEL(os); 1136 throw ioe; 1137 } 1138 return getWriter(os, charset); 1139 } 1140 1141 /** 1142 * @deprecated use instead <code>{@link #getWriter(Resource, Charset, boolean)}</code> 1143 * returns a Reader for the given File and charset (Automaticly check BOM Files) 1144 * @param file 1145 * @param charset 1146 * @return Reader 1147 * @throws IOException 1148 */ 1149 public static Writer getWriter(File file, String charset, boolean append) throws IOException { 1150 OutputStream os=null; 1151 try { 1152 os=new FileOutputStream(file,append); 1153 } 1154 catch(IOException ioe) { 1155 closeEL(os); 1156 throw ioe; 1157 } 1158 return getWriter(os, charset); 1159 } 1160 1161 1162 /** 1163 * @deprecated use instead <code>{@link #getWriter(OutputStream, Charset)}</code> 1164 * @param os 1165 * @param charset 1166 * @return 1167 * @throws IOException 1168 */ 1169 public static Writer getWriter(OutputStream os, String charset) throws IOException { 1170 return getWriter(os, CharsetUtil.toCharset(charset)); 1171 } 1172 1173 /** 1174 * returns a Reader for the given InputStream 1175 * @param is 1176 * @param charset 1177 * @return Reader 1178 * @throws IOException 1179 */ 1180 public static Writer getWriter(OutputStream os, Charset charset) throws IOException { 1181 if(charset==null) charset=SystemUtil.getCharset(); 1182 return new BufferedWriter(new OutputStreamWriter(os,charset)); 1183 } 1184 1185 public static String read(Reader reader, int size) throws IOException { 1186 return read(reader, new char[size]); 1187 } 1188 1189 public static String read(Reader reader,char[] carr) throws IOException { 1190 int rst = reader.read(carr); 1191 if(rst==-1)return null; 1192 return new String(carr,0,rst); 1193 } 1194 1195 1196 private static class Copy extends Thread { 1197 1198 private Reader r; 1199 private Writer w; 1200 private int blockSize; 1201 private long timeout; 1202 private boolean finished; 1203 private Throwable t; 1204 private Object notifier=new Object(); 1205 1206 private Copy(Reader r, Writer w, int blockSize, long timeout) { 1207 this.r=r; 1208 this.w=w; 1209 this.blockSize=blockSize; 1210 this.timeout=timeout; 1211 } 1212 1213 @Override 1214 public void run(){ 1215 try { 1216 IOUtil.copy(r, w, blockSize, -1); 1217 } 1218 catch(Throwable t) { 1219 ExceptionUtil.rethrowIfNecessary(t); 1220 this.t=t; 1221 } 1222 finally { 1223 finished=true; 1224 SystemUtil.notify(notifier); 1225 } 1226 } 1227 } 1228} 1229