001    package railo.commons.io;
002    
003    import java.io.BufferedInputStream;
004    import java.io.BufferedOutputStream;
005    import java.io.BufferedReader;
006    import java.io.BufferedWriter;
007    import java.io.ByteArrayInputStream;
008    import java.io.ByteArrayOutputStream;
009    import java.io.Closeable;
010    import java.io.File;
011    import java.io.FileOutputStream;
012    import java.io.IOException;
013    import java.io.InputStream;
014    import java.io.InputStreamReader;
015    import java.io.OutputStream;
016    import java.io.OutputStreamWriter;
017    import java.io.PrintStream;
018    import java.io.Reader;
019    import java.io.StringWriter;
020    import java.io.UnsupportedEncodingException;
021    import java.io.Writer;
022    import java.lang.reflect.Method;
023    import java.util.LinkedList;
024    import java.util.zip.ZipFile;
025    
026    import javax.mail.Transport;
027    
028    import net.sf.jmimemagic.Magic;
029    import net.sf.jmimemagic.MagicMatch;
030    import railo.commons.io.res.Resource;
031    import railo.commons.net.URLEncoder;
032    import railo.runtime.exp.PageException;
033    
034    import com.lowagie.text.Document;
035    
036    /**
037     * I/O Util 
038     */
039    public final class IOUtil {
040    
041        /**
042         * copy a inputstream to a outputstream
043         * @param in 
044         * @param out
045         * @param closeIS 
046         * @param closeOS 
047         * @throws IOException
048         */
049        public static final void copy(InputStream in, OutputStream out, boolean closeIS, boolean closeOS) throws IOException {
050            try {
051                copy(in,out,0xffff);
052            }
053            finally {
054                if(closeIS)closeEL(in);
055                if(closeOS)closeEL(out);
056            }
057        }
058        
059        /**
060         * copy a inputstream to a outputstream
061         * @param in 
062         * @param out
063         * @param closeIS 
064         * @param closeOS 
065         * @throws IOException
066         */
067        public static final void merge(InputStream in1, InputStream in2, OutputStream out, boolean closeIS1, boolean closeIS2, boolean closeOS) throws IOException {
068            try {
069                merge(in1,in2,out,0xffff);
070            }
071            finally {
072                if(closeIS1)closeEL(in1);
073                if(closeIS2)closeEL(in2);
074                if(closeOS)closeEL(out);
075            }
076        }
077        
078        /**
079         * copy a inputstream to a outputstream
080         * @param in 
081         * @param out
082         * @param closeIS 
083         * @param closeOS 
084         * @throws IOException
085         */
086        public static final void copy(OutputStream out, InputStream in,boolean closeIS, boolean closeOS) throws IOException {
087            copy(in,out,closeIS,closeOS);
088        }
089        
090            /**
091             * copy a input resource to a output resource
092         * @param in
093             * @param out
094             * @throws IOException
095             */
096            public static void copy(Resource in, Resource out) throws IOException {
097                    in.copyTo(out, false);
098            }
099            
100            public static void merge(Resource in1, Resource in2, Resource out) throws IOException {
101                    InputStream is1=null;
102                    InputStream is2=null;
103                    OutputStream os=null;
104                    try {
105                            is1=toBufferedInputStream(in1.getInputStream());
106                            is2=toBufferedInputStream(in2.getInputStream());
107                            os=toBufferedOutputStream(out.getOutputStream());
108                    }
109                    catch(IOException ioe) {
110                            IOUtil.closeEL(is1);
111                            IOUtil.closeEL(is2);
112                            IOUtil.closeEL(os);
113                            throw ioe;
114                    }
115                    merge(is1,is2,os,true,true,true);
116            }
117    
118            /**
119             * copy a input resource to a output resource
120         * @param in
121             * @param out
122             * @throws IOException
123             */
124            public static void copy(InputStream is, Resource out, boolean closeIS) throws IOException {
125                    OutputStream os=null;
126                    try {
127                            os=toBufferedOutputStream(out.getOutputStream());
128                    }
129                    catch(IOException ioe) {
130                            IOUtil.closeEL(os);
131                            throw ioe;
132                    }
133                    copy(is,os,closeIS,true);
134            }
135        
136            /**
137             * copy a input resource to a output resource
138         * @param in
139             * @param out
140             * @throws IOException
141             */
142            public static void copy(Resource in, OutputStream os, boolean closeOS) throws IOException {
143                    InputStream is=null;
144                    try {
145                            is=toBufferedInputStream(in.getInputStream());
146                    }
147                    catch(IOException ioe) {
148                            IOUtil.closeEL(is);
149                            throw ioe;
150                    }
151                    copy(is,os,true,closeOS);
152            }
153        
154        public static final void copy(InputStream in, OutputStream out, int offset, int length) throws IOException {
155            copy(in, out, offset, length,0xffff);
156        }
157        
158        public static final void copy(InputStream in, OutputStream out, long offset, long length) throws IOException {
159            int len;
160            byte[] buffer;
161            int block=0xffff;
162            
163            // first offset to start
164            if(offset>0) {
165                    long skipped=0;
166                    try{
167                            skipped = in.skip(offset);
168                    }
169                    catch(Throwable t){}
170                    
171                            if(skipped<=0) {
172                            while(true) {
173                            if(block>offset)block=(int)offset;
174                            buffer = new byte[block];
175                            len = in.read(buffer);
176                            if(len==-1) throw new IOException("reading offset is bigger than input itself");
177                            //dnos.write(buffer, 0, len);
178                            offset-=len;
179                            if(offset<=0) break;
180                        }
181                    }
182            }
183            
184            // write part
185            if(length<0) {
186                    copy(in, out,block);
187                    return;
188            }
189            
190            while(true) {
191                    if(block>length)block=(int) length;
192                    buffer = new byte[block];
193                    len = in.read(buffer);
194                    if(len==-1) break;
195                    out.write(buffer, 0, len);
196                    length-=len;
197                    if(length<=0) break;
198            }
199        }
200        
201        public static final void copy(InputStream in, OutputStream out, int offset, int length, int blockSize) throws IOException {
202    
203            int len;
204            byte[] buffer;
205            int block;//0xffff;
206            
207            // first offset to start
208            if(offset>0) {
209                    long skipped=0;
210                    try{
211                            skipped = in.skip(offset);
212                    }
213                    catch(Throwable t){}
214                    
215                            if(skipped<=0) {
216                            block = blockSize;//0xffff;
217                            while(true) {
218                            if(block>offset)block=offset;
219                            buffer = new byte[block];
220                            len = in.read(buffer);
221                            if(len==-1) throw new IOException("reading offset is bigger than input itself");
222                            //dnos.write(buffer, 0, len);
223                            offset-=len;
224                            if(offset<=0) break;
225                        }
226                            }
227            }
228            
229            // write part
230            if(length<0) {
231                    copy(in, out,blockSize);
232                    return;
233            }
234            block = blockSize;//0xffff;
235            while(true) {
236                    if(block>length)block=length;
237                    buffer = new byte[block];
238                    len = in.read(buffer);
239                    if(len==-1) break;
240                    out.write(buffer, 0, len);
241                    length-=len;
242                    if(length<=0) break;
243            }
244        }
245    
246            /**
247         * copy a inputstream to a outputstream
248         * @param in 
249         * @param out
250         * @param blockSize 
251         * @throws IOException
252         */
253        private static final void copy(InputStream in, OutputStream out, int blockSize) throws IOException {
254            byte[] buffer = new byte[blockSize];
255            int len;
256            while((len = in.read(buffer)) !=-1) {
257              out.write(buffer, 0, len);
258            }
259        }
260        
261        private static final void merge(InputStream in1, InputStream in2, OutputStream out, int blockSize) throws IOException {
262            copy(in1, out,blockSize);
263            copy(in2, out,blockSize);
264        }
265        
266        /**
267         * copy a reader to a writer
268         * @param r 
269         * @param w 
270         * @throws IOException
271         */
272        private static final void copy(Reader r, Writer w) throws IOException {
273            copy(r,w,0xffff);
274        }
275        
276        /**
277         * copy a reader to a writer
278         * @param reader 
279         * @param writer 
280         * @param closeReader 
281         * @param closeWriter 
282         * @throws IOException
283         */
284        public static final void copy(Reader reader, Writer writer, boolean closeReader, boolean closeWriter) throws IOException {
285            try {
286                copy(reader,writer,0xffff);
287            }
288            finally {
289                if(closeReader)closeEL(reader);
290                if(closeWriter)closeEL(writer);
291            }
292        }
293        
294        /**
295         * copy a reader to a writer
296         * @param r 
297         * @param w 
298         * @param blockSize 
299         * @throws IOException
300         */
301        private static final void copy(Reader r, Writer w, int blockSize) throws IOException {
302            char[] buffer = new char[blockSize];
303            int len;
304    
305            while((len = r.read(buffer)) !=-1)
306              w.write(buffer, 0, len);
307        }
308        
309        /** 
310         * copy content of in file to out File 
311         * @param in input 
312         * @param out output 
313         * @throws IOException 
314         */ 
315        public void copy(File in,File out) throws IOException {
316            InputStream is=null;
317            OutputStream os=null;
318                    try {
319                            is = new BufferedFileInputStream(in);
320                            os = new BufferedFileOutputStream(out);
321                    } 
322                    catch (IOException ioe) {
323                            closeEL(is,os);
324                            throw ioe;
325                    }
326            copy(is,os,true,true); 
327        } 
328    
329        
330        
331        
332    
333        /**
334         * close inputstream without a Exception
335         * @param is 
336         * @param os 
337         */
338         public static void closeEL(InputStream is, OutputStream os) {
339              closeEL(is);
340              closeEL(os);
341          }
342         
343        /**
344         * close inputstream without a Exception
345         * @param is 
346         */
347         public static void closeEL(InputStream is) {
348             try {
349                     if(is!=null)is.close();
350             } 
351             //catch (AlwaysThrow at) {throw at;}
352             catch (Throwable t) {}
353         }
354         
355         public static void closeEL(ZipFile zip) {
356             try {
357                     if(zip!=null)zip.close();
358             } 
359             //catch (AlwaysThrow at) {throw at;}
360             catch (Throwable t) {}
361         }
362         
363         /**
364          * close outputstream without a Exception
365          * @param os 
366          */
367         public static void closeEL(OutputStream os) {
368               try {
369                   if(os!=null)os.close();
370             } 
371             //catch (AlwaysThrow at) {throw at;}
372             catch (Throwable e) {}
373           }
374         
375         /**
376          * close Reader without a Exception
377          * @param r 
378          */
379         public static void closeEL(Reader r) {
380               try {
381                   if(r!=null)r.close();
382             } 
383             //catch (AlwaysThrow at) {throw at;}
384             catch (Throwable e) {}
385           }
386    
387         
388         /**
389          * close Closeable without a Exception
390          * @param r 
391          */
392         public static void closeEL(Closeable c ) {
393               try {
394                   if(c!=null)c.close();
395             } 
396             //catch (AlwaysThrow at) {throw at;}
397             catch (Throwable e) {}
398           }
399         
400         /**
401          * close Writer without a Exception
402          * @param w 
403          */
404         public static void closeEL(Writer w) {
405             try {
406                   if(w!=null)w.close();
407             } 
408             //catch (AlwaysThrow at) {throw at;}
409             catch (Throwable e) {}
410         }
411         
412         /**
413          * close Writer without a Exception
414          * @param w 
415          */
416         public static void closeEL(Transport t) {
417               try {
418                   if(t!=null && t.isConnected())t.close();
419             } 
420             catch (Throwable e) {}
421         }
422         
423         
424         public static void closeEL(Document doc) {
425               try {
426                   if(doc!=null)doc.close();
427             } 
428             catch (Throwable e) {}
429         }
430         
431         
432         
433         /**
434         * call close method from any Object with a close method.
435         * @param obj
436         */
437         public static void closeEL(Object obj) {
438             if(obj instanceof InputStream)         IOUtil.closeEL((InputStream)obj);
439             else if(obj instanceof OutputStream)   IOUtil.closeEL((OutputStream)obj);
440             else if(obj instanceof Writer)         IOUtil.closeEL((Writer)obj);
441             else if(obj instanceof Reader)         IOUtil.closeEL((Reader)obj);
442             else if(obj instanceof Closeable)         IOUtil.closeEL((Closeable)obj);
443             else if(obj instanceof ZipFile)        IOUtil.closeEL((ZipFile)obj);
444             else {
445                 try {
446                     Method method = obj.getClass().getMethod("close",new Class[0]);
447                     method.invoke(obj,new Object[0]);
448                 } 
449                 catch (Throwable e) {}
450             }
451         }
452    
453            public static Reader getReader(Resource res, String charset) throws IOException {
454                    /*
455                    00 00 FE FF     UTF-32, big-endian
456                    FF FE 00 00     UTF-32, little-endian
457                    */
458                    
459                    
460                    InputStream is=null;
461                    try {
462                            is = res.getInputStream();
463                            boolean markSupported=is.markSupported();
464                    if(markSupported) is.mark(4);
465                    int first = is.read();
466                    int second = is.read();
467                    // FE FF        UTF-16, big-endian
468                    if (first == 0xFE && second == 0xFF)    {
469                            return _getReader(is, "UTF-16BE");
470                    }
471                    // FF FE        UTF-16, little-endian
472                    if (first == 0xFF && second == 0xFE)    {
473                            return _getReader(is, "UTF-16LE");
474                    }
475                    
476                    int third=is.read();
477                    // EF BB BF     UTF-8
478                    if (first == 0xEF && second == 0xBB && third == 0xBF)    {
479                            //is.reset();
480                                    return _getReader(is, "utf-8");
481                    }
482                            /*
483                    int forth=is.read();
484                    // 00 00 FE FF          UTF-32, big-endian
485                    if (first == 0x00 && second == 0x00 && third == 0xFE  && forth == 0xFF)    {
486                            is.reset();
487                                    return _getReader(is, "utf-32");
488                    }
489                    // FF FE 00 00  UTF-32, little-endian
490                    if (first == 0xFF && second == 0xFE && third == 0x00  && forth == 0x00)    {
491                            is.reset();
492                                    return _getReader(is, "utf-32");
493                    }*/
494                    
495                    if(markSupported) {
496                            is.reset();
497                            return _getReader(is,charset);
498                    }
499                    }
500                    catch(IOException ioe) {
501                            IOUtil.closeEL(is);
502                            throw ioe;
503                    }
504                    
505            // when mark not supported return new reader
506            closeEL(is);
507            is=null;
508                    try {
509                            is=res.getInputStream();
510                    }
511                    catch(IOException ioe) {
512                            closeEL(is);
513                            throw ioe;
514                    }
515            return _getReader(is, charset);             
516       }
517            
518    
519     public static Reader getReader(InputStream is, String charset) throws IOException {
520                    
521                    boolean markSupported=is.markSupported();
522            if(!markSupported) return _getReader(is, charset);
523            
524            if(markSupported) is.mark(4);
525            
526            int first = is.read();
527            int second = is.read();
528            // FE FF        UTF-16, big-endian
529            if (first == 0xFE && second == 0xFF)    {
530                    //is.reset();
531                            return _getReader(is, "utf-16BE");
532            }
533            // FF FE        UTF-16, little-endian
534            if (first == 0xFF && second == 0xFE)    {
535                    //is.reset();
536                            return _getReader(is, "UTF-16LE");
537            }
538            
539            int third=is.read();
540            // EF BB BF     UTF-8
541            if (first == 0xEF && second == 0xBB && third == 0xBF)    {
542                            //is.reset();
543                            //print.err("reset");
544                    return _getReader(is, "utf-8");
545            }
546    
547            /*int forth=is.read();
548            // 00 00 FE FF          UTF-32, big-endian
549            if (first == 0x00 && second == 0x00 && third == 0xFE  && forth == 0xFF)    {
550                    is.reset();
551                            return _getReader(is, "utf-32");
552            }
553            // FF FE 00 00  UTF-32, little-endian
554            if (first == 0xFF && second == 0xFE && third == 0x00  && forth == 0x00)    {
555                    is.reset();
556                            return _getReader(is, "utf-32");
557            }*/
558            
559            
560            
561            
562                    /*if(markSupported) is.mark(3);
563                    if (is.read() == 0xEF && is.read() == 0xBB && is.read() == 0xBF)    {
564                            return _getReader(is, "utf-8");
565            }*/
566                    is.reset();
567            return _getReader(is,charset);       
568       }
569            
570            
571         
572         /* *
573          * returns a Reader for the given File and charset (Automaticly check BOM Files)
574          * @param file
575          * @param charset
576          * @return Reader
577          * @throws IOException
578          * /
579         public static Reader getReader(File file, String charset) throws IOException {
580            InputStream is=null;
581                    try {
582                            is=new FileInputStream(file);
583                    }
584                    catch(IOException ioe) {
585                            closeEL(is);
586                            throw ioe;
587                    }
588            return _getReader(is, charset);
589        }*/
590         
591         /**
592          * returns a Reader for the given InputStream
593          * @param is
594          * @param charset
595          * @return Reader
596          * @throws IOException
597          */
598         private static Reader _getReader(InputStream is, String charset) throws IOException {
599             if(charset==null) charset=SystemUtil.getCharset();
600             return new BufferedReader(new InputStreamReader(is,charset.trim()));
601         }
602    
603        /**
604         * reads string data from a InputStream
605         * @param is
606         * @param charset 
607         * @return string from inputstream
608        * @throws IOException 
609        */
610         public static String toString(InputStream is, String charset) throws IOException {
611             return toString(getReader(is,charset));
612         }
613         
614         public static String toString(byte[] barr, String charset) throws IOException {
615             return toString(getReader(new ByteArrayInputStream(barr),charset));
616         }
617    
618       /**
619        * reads String data from a Reader
620        * @param reader
621        * @return readed string
622        * @throws IOException
623        */
624       public static String toString(Reader reader) throws IOException {
625           StringWriter sw=new StringWriter(512);
626           copy(toBufferedReader(reader),sw);
627           sw.close();
628           return sw.toString();
629       }
630    
631       /**
632        * reads String data from a Reader
633        * @param reader
634        * @return readed string
635        * @throws IOException
636        */
637       public static String toString(Reader reader,boolean buffered) throws IOException {
638           StringWriter sw=new StringWriter(512);
639           if(buffered)copy(toBufferedReader(reader),sw);
640           else copy(reader,sw);
641           sw.close();
642           return sw.toString();
643       }
644    
645       /**
646        * reads String data from File
647         * @param file 
648         * @param charset 
649         * @return readed string
650        * @throws IOException
651        * /
652       public static String toString(File file, String charset) throws IOException {
653           Reader r = null;
654           try {
655               r=getReader(file,charset);
656               String str = toString(r);
657               return str;
658           }
659           finally {
660               closeEL(r);
661           }
662       }*/
663    
664       /**
665        * reads String data from File
666         * @param file 
667         * @param charset 
668         * @return readed string
669        * @throws IOException
670        */
671       public static String toString(Resource file, String charset) throws IOException {
672           Reader r = null;
673           try {
674               r = getReader(file,charset);
675               String str = toString(r);
676               return str;
677           }
678           finally {
679               closeEL(r);
680           }
681       }
682    
683        /**
684         * @param reader Reader to get content from it
685         * @return returns the content of the file as String Array (Line by Line)
686         * @throws IOException
687         */
688        public static String[] toStringArray(Reader reader) throws IOException {
689            if(reader==null)return new String[0];
690            BufferedReader br = new BufferedReader(reader); 
691            LinkedList<String> list=new LinkedList<String>();
692            
693            String line;
694            while((line=br.readLine())!=null)   {
695                list.add(line);
696            }
697            br.close();
698            String[] content=new String[list.size()];
699            int count=0;
700            while(!list.isEmpty()) {
701                content[count++]=list.removeFirst();
702            }
703            return content;
704        }
705    
706        /**
707         * writes a String to a object
708         * @param file 
709         * @param string String to write to file
710         * @param charset
711         * @param append  append to cuuretn data or overwrite existing data
712         * @throws IOException
713         */
714        public static void write(File file, String string, String charset, boolean append) throws IOException {
715            if(charset==null) {
716                charset=SystemUtil.getCharset();
717            }
718                    
719            
720            OutputStreamWriter writer=null;
721            try {
722                writer=new OutputStreamWriter(new BufferedFileOutputStream(file,append),charset);
723                writer.write(string);
724                
725            }
726            finally {
727                closeEL(writer);
728            }
729        }
730        
731        public static void write(Resource res, String string, String charset, boolean append) throws IOException {
732            if(charset==null) {
733                charset=SystemUtil.getCharset();
734            }
735                    
736            
737            Writer writer=null;
738            try {
739                writer=IOUtil.getWriter(res, charset,append);
740                writer.write(string);
741            }
742            finally {
743                closeEL(writer);
744            }
745        }
746    
747    
748        public static void write(Resource res, byte[] barr) throws IOException {
749            ByteArrayInputStream bais = new ByteArrayInputStream(barr);
750            OutputStream os=IOUtil.toBufferedOutputStream(res.getOutputStream());
751            IOUtil.copy(bais, os, true, true);
752        }
753    
754        public static void write(Resource res, byte[] barr, boolean append) throws IOException {
755            ByteArrayInputStream bais = new ByteArrayInputStream(barr);
756            OutputStream os=IOUtil.toBufferedOutputStream(res.getOutputStream(append));
757            IOUtil.copy(bais, os, true, true);
758        }
759        
760        /**
761         * @param file 
762         * @return returns the Content of the file as byte array
763         * @throws IOException
764         */
765        public static byte[] toBytes(File file) throws IOException {
766            BufferedFileInputStream bfis = null;
767            try {
768                    bfis = new BufferedFileInputStream(file);
769                byte[] barr = toBytes(bfis);
770                return barr;
771            }
772            finally {
773                closeEL(bfis);
774            }
775        }
776        
777        /**
778         * @param res 
779         * @return returns the Content of the file as byte array
780         * @throws IOException
781         */
782        public static byte[] toBytes(Resource res) throws IOException {
783            BufferedInputStream bfis = null;
784            try {
785                    bfis = toBufferedInputStream(res.getInputStream());
786                byte[] barr = toBytes(bfis);
787                return barr;
788            }
789            finally {
790                closeEL(bfis);
791            }
792        }
793    
794        public static BufferedInputStream toBufferedInputStream(InputStream is) {
795                    if(is instanceof BufferedInputStream) return (BufferedInputStream) is;
796                    return new BufferedInputStream(is);
797            }
798        
799        public static BufferedOutputStream toBufferedOutputStream(OutputStream os) {
800                    if(os instanceof BufferedOutputStream) return (BufferedOutputStream) os;
801                    return new BufferedOutputStream(os);
802            }
803        
804        public static BufferedReader toBufferedReader(Reader r) {
805                    if(r instanceof BufferedReader) return (BufferedReader) r;
806                    return new BufferedReader(r);
807            }
808        
809        public static BufferedReader getBufferedReader(Resource res,String charset) throws IOException {
810                    return toBufferedReader(getReader(res, charset));
811            }
812        
813        public static BufferedWriter toBufferedWriter(Writer w) {
814                    if(w instanceof BufferedWriter) return (BufferedWriter) w;
815                    return new BufferedWriter(w);
816            }
817    
818            /**
819         * @param is 
820         * @return returns the Content of the file as byte array
821         * @throws IOException
822         */
823        public static byte[] toBytes(InputStream is) throws IOException {
824           return toBytes(is,false);
825        }
826        
827    
828        public static byte[] toBytes(InputStream is, boolean closeStream) throws IOException {
829            ByteArrayOutputStream baos = new ByteArrayOutputStream();
830            copy(is,baos,closeStream,true);
831            return baos.toByteArray();
832        }
833    
834        public static byte[] toBytesMax(InputStream is, int max) throws IOException {
835            ByteArrayOutputStream baos = new ByteArrayOutputStream();
836            copy(is,baos,0,max);
837            return baos.toByteArray();
838        }
839    
840        /**
841         * flush OutputStream without a Exception
842         * @param os
843         */
844        public static void flushEL(OutputStream os) {
845            try {
846                if(os!=null)os.flush();
847            } catch (Exception e) {}
848        }
849    
850        /**
851         * flush OutputStream without a Exception
852         * @param os
853         */
854        public static void flushEL(Writer w) {
855            try {
856                if(w!=null)w.flush();
857            } catch (Exception e) {}
858        }
859        
860        /**
861         * check if given encoding is ok
862         * @param encoding
863         * @throws PageException 
864         */
865        public static void checkEncoding(String encoding) throws IOException {
866                    try {
867                            URLEncoder.encode("", encoding);
868                    } catch (UnsupportedEncodingException e) {
869                            throw new IOException("invalid encoding ["+encoding+"]");
870                    }
871            }
872        
873        /**
874         * return the mime type of a file, dont check extension
875         * @param barr
876         * @param defaultValue 
877         * @return mime type of the file
878         */
879        public static String getMimeType(InputStream is, String defaultValue) {
880            try {
881                            return getMimeType(IOUtil.toBytesMax(is,1000), defaultValue);
882                    } catch (IOException e) {
883                            return defaultValue;
884                    }
885            
886            
887            /*try {
888                            return URLConnection.guessContentTypeFromStream(is);
889                    } catch (Throwable t) {
890                            return defaultValue;
891                    }*/
892                    
893            /*try {
894                            return getMimeType(IOUtil.toBytesMax(is,1000), defaultValue);
895                    } catch (IOException e) {
896                            return defaultValue;
897                    }*/
898        }
899        
900        
901        /**
902         * return the mime type of a file, dont check extension
903         * @param barr
904         * @return mime type of the file
905         * @throws IOException 
906         */
907        public static String getMimeType(byte[] barr, String defaultValue) {
908            
909            //String mt = getMimeType(new ByteArrayInputStream(barr), null);
910            //if(!StringUtil.isEmpty(mt,true)) return mt;
911            
912            PrintStream out = System.out;
913            try {
914                    System.setOut(new PrintStream(DevNullOutputStream.DEV_NULL_OUTPUT_STREAM));
915                MagicMatch match = Magic.getMagicMatch(barr);
916                return match.getMimeType();
917            } 
918            catch (Throwable t) {
919                            return defaultValue;
920            }
921            finally {
922                    System.setOut(out);
923            }
924        }
925        
926            public static Writer getWriter(Resource res, String charset) throws IOException {
927                    OutputStream os=null;
928                    try {
929                            os=res.getOutputStream();
930                    }
931                    catch(IOException ioe) {
932                            closeEL(os);
933                            throw ioe;
934                    }
935                    return getWriter(os, charset);
936             
937            }
938        
939            public static Writer getWriter(Resource res, String charset, boolean append) throws IOException {
940                    OutputStream os=null;
941                    try {
942                            os=res.getOutputStream(append);
943                    }
944                    catch(IOException ioe) {
945                            closeEL(os);
946                            throw ioe;
947                    }
948                    return getWriter(os, charset);
949            }
950        
951        /**
952         * returns a Reader for the given File and charset (Automaticly check BOM Files)
953         * @param file
954         * @param charset
955         * @return Reader
956         * @throws IOException
957         */
958        public static Writer getWriter(File file, String charset) throws IOException {
959            OutputStream os=null;
960                    try {
961                            os=new FileOutputStream(file);
962                    }
963                    catch(IOException ioe) {
964                            closeEL(os);
965                            throw ioe;
966                    }
967                    return getWriter(os, charset);
968       }
969        
970        /**
971         * returns a Reader for the given File and charset (Automaticly check BOM Files)
972         * @param file
973         * @param charset
974         * @return Reader
975         * @throws IOException
976         */
977        public static Writer getWriter(File file, String charset, boolean append) throws IOException {
978            OutputStream os=null;
979                    try {
980                            os=new FileOutputStream(file,append);
981                    }
982                    catch(IOException ioe) {
983                            closeEL(os);
984                            throw ioe;
985                    }
986                    return getWriter(os, charset);
987       }
988         
989    
990        /**
991         * returns a Reader for the given InputStream
992         * @param is
993         * @param charset
994         * @return Reader
995         * @throws IOException
996         */
997        public static Writer getWriter(OutputStream os, String charset) throws IOException {
998             if(charset==null) charset=SystemUtil.getCharset();
999            return new BufferedWriter(new OutputStreamWriter(os,charset.trim()));
1000        }
1001    
1002            public static String read(Reader reader, int size) throws IOException {
1003                    return read(reader, new char[size]);
1004            }
1005            
1006            public static String read(Reader reader,char[] carr) throws IOException {
1007                    int rst = reader.read(carr);
1008                    if(rst==-1)return null;
1009                    return new String(carr,0,rst);
1010            }
1011    }