001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.wicket.util.io;
018:
019: import java.io.BufferedInputStream;
020: import java.io.BufferedReader;
021: import java.io.CharArrayWriter;
022: import java.io.IOException;
023: import java.io.InputStream;
024: import java.io.InputStreamReader;
025: import java.io.OutputStream;
026: import java.io.OutputStreamWriter;
027: import java.io.Reader;
028: import java.io.StringWriter;
029: import java.io.Writer;
030:
031: /**
032: * General IO Stream manipulation.
033: * <p>
034: * This class provides static utility methods for input/output operations.
035: * <ul>
036: * <li>closeQuietly - these methods close a stream ignoring nulls and
037: * exceptions
038: * <li>toXxx - these methods read data from a stream
039: * <li>write - these methods write data to a stream
040: * <li>copy - these methods copy all the data from one stream to another
041: * <li>contentEquals - these methods compare the content of two streams
042: * </ul>
043: * <p>
044: * The byte-to-char methods and char-to-byte methods involve a conversion step.
045: * Two methods are provided in each case, one that uses the platform default
046: * encoding and the other which allows you to specify an encoding. You are
047: * encouraged to always specify an encoding because relying on the platform
048: * default can lead to unexpected results, for example when moving from
049: * development to production.
050: * <p>
051: * All the methods in this class that read a stream are buffered internally.
052: * This means that there is no cause to use a <code>BufferedInputStream</code>
053: * or <code>BufferedReader</code>. The default buffer size of 4K has been
054: * show to be efficient in tests.
055: * <p>
056: * Wherever possible, the methods in this class do <em>not</em> flush or close
057: * the stream. This is to avoid making non-portable assumptions about the
058: * streams' origin and further use. Thus the caller is still responsible for
059: * closing streams after use.
060: * <p>
061: * Origin of code: Apache Avalon (Excalibur)
062: *
063: * @author Peter Donald
064: * @author Jeff Turner
065: * @author Matthew Hawthorne
066: * @author Stephen Colebourne
067: * @author Gareth Davis
068: * @version CVS $Revision$ $Date$
069: */
070: public final class IOUtils {
071: // NOTE: This class is focussed on InputStream, OutputStream, Reader and
072: // Writer. Each method should take at least one of these as a parameter.
073: // NOTE: This class should not depend on any other classes
074:
075: /**
076: * The default buffer size to use.
077: */
078: private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
079:
080: /**
081: * Instances should NOT be constructed in standard programming.
082: */
083: public IOUtils() {
084: }
085:
086: // -----------------------------------------------------------------------
087: /**
088: * Unconditionally close an <code>Reader</code>.
089: * <p>
090: * Equivalent to {@link Reader#close()}, except any exceptions will be
091: * ignored. This is typically used in finally blocks.
092: *
093: * @param input
094: * the Reader to close, may be null or already closed
095: */
096: public static void closeQuietly(Reader input) {
097: if (input != null) {
098: try {
099: input.close();
100: } catch (Exception e) {
101: // ignore
102: }
103: }
104: }
105:
106: /**
107: * Unconditionally close a <code>Writer</code>.
108: * <p>
109: * Equivalent to {@link Writer#close()}, except any exceptions will be
110: * ignored. This is typically used in finally blocks.
111: *
112: * @param output
113: * the Writer to close, may be null or already closed
114: */
115: public static void closeQuietly(Writer output) {
116: if (output != null) {
117: try {
118: output.close();
119: } catch (Exception e) {
120: // ignore
121: }
122: }
123: }
124:
125: /**
126: * Unconditionally close an <code>InputStream</code>.
127: * <p>
128: * Equivalent to {@link InputStream#close()}, except any exceptions will be
129: * ignored. This is typically used in finally blocks.
130: *
131: * @param input
132: * the InputStream to close, may be null or already closed
133: */
134: public static void closeQuietly(InputStream input) {
135: if (input != null) {
136: try {
137: input.close();
138: } catch (Exception e) {
139: // ignore
140: }
141: }
142: }
143:
144: /**
145: * Unconditionally close an <code>OutputStream</code>.
146: * <p>
147: * Equivalent to {@link OutputStream#close()}, except any exceptions will
148: * be ignored. This is typically used in finally blocks.
149: *
150: * @param output
151: * the OutputStream to close, may be null or already closed
152: */
153: public static void closeQuietly(OutputStream output) {
154: if (output != null) {
155: try {
156: output.close();
157: } catch (Exception e) {
158: // ignore
159: }
160: }
161: }
162:
163: // read toByteArray
164: // -----------------------------------------------------------------------
165: /**
166: * Get the contents of an <code>InputStream</code> as a
167: * <code>byte[]</code>.
168: * <p>
169: * This method buffers the input internally, so there is no need to use a
170: * <code>BufferedInputStream</code>.
171: *
172: * @param input
173: * the <code>InputStream</code> to read from
174: * @return the requested byte array
175: * @throws NullPointerException
176: * if the input is null
177: * @throws IOException
178: * if an I/O error occurs
179: */
180: public static byte[] toByteArray(InputStream input)
181: throws IOException {
182: ByteArrayOutputStream output = new ByteArrayOutputStream();
183: copy(input, output);
184: return output.toByteArray();
185: }
186:
187: /**
188: * Get the contents of a <code>Reader</code> as a <code>byte[]</code>
189: * using the default character encoding of the platform.
190: * <p>
191: * This method buffers the input internally, so there is no need to use a
192: * <code>BufferedReader</code>.
193: *
194: * @param input
195: * the <code>Reader</code> to read from
196: * @return the requested byte array
197: * @throws NullPointerException
198: * if the input is null
199: * @throws IOException
200: * if an I/O error occurs
201: */
202: public static byte[] toByteArray(Reader input) throws IOException {
203: ByteArrayOutputStream output = new ByteArrayOutputStream();
204: copy(input, output);
205: return output.toByteArray();
206: }
207:
208: /**
209: * Get the contents of a <code>Reader</code> as a <code>byte[]</code>
210: * using the specified character encoding.
211: * <p>
212: * Character encoding names can be found at <a
213: * href="http://www.iana.org/assignments/character-sets">IANA</a>.
214: * <p>
215: * This method buffers the input internally, so there is no need to use a
216: * <code>BufferedReader</code>.
217: *
218: * @param input
219: * the <code>Reader</code> to read from
220: * @param encoding
221: * the encoding to use, null means platform default
222: * @return the requested byte array
223: * @throws NullPointerException
224: * if the input is null
225: * @throws IOException
226: * if an I/O error occurs
227: * @since 1.1
228: */
229: public static byte[] toByteArray(Reader input, String encoding)
230: throws IOException {
231: ByteArrayOutputStream output = new ByteArrayOutputStream();
232: copy(input, output, encoding);
233: return output.toByteArray();
234: }
235:
236: // read char[]
237: // -----------------------------------------------------------------------
238: /**
239: * Get the contents of an <code>InputStream</code> as a character array
240: * using the default character encoding of the platform.
241: * <p>
242: * This method buffers the input internally, so there is no need to use a
243: * <code>BufferedInputStream</code>.
244: *
245: * @param is
246: * the <code>InputStream</code> to read from
247: * @return the requested character array
248: * @throws NullPointerException
249: * if the input is null
250: * @throws IOException
251: * if an I/O error occurs
252: */
253: public static char[] toCharArray(InputStream is) throws IOException {
254: CharArrayWriter output = new CharArrayWriter();
255: copy(is, output);
256: return output.toCharArray();
257: }
258:
259: /**
260: * Get the contents of an <code>InputStream</code> as a character array
261: * using the specified character encoding.
262: * <p>
263: * Character encoding names can be found at <a
264: * href="http://www.iana.org/assignments/character-sets">IANA</a>.
265: * <p>
266: * This method buffers the input internally, so there is no need to use a
267: * <code>BufferedInputStream</code>.
268: *
269: * @param is
270: * the <code>InputStream</code> to read from
271: * @param encoding
272: * the encoding to use, null means platform default
273: * @return the requested character array
274: * @throws NullPointerException
275: * if the input is null
276: * @throws IOException
277: * if an I/O error occurs
278: */
279: public static char[] toCharArray(InputStream is, String encoding)
280: throws IOException {
281: CharArrayWriter output = new CharArrayWriter();
282: copy(is, output, encoding);
283: return output.toCharArray();
284: }
285:
286: /**
287: * Get the contents of a <code>Reader</code> as a character array.
288: * <p>
289: * This method buffers the input internally, so there is no need to use a
290: * <code>BufferedReader</code>.
291: *
292: * @param input
293: * the <code>Reader</code> to read from
294: * @return the requested character array
295: * @throws NullPointerException
296: * if the input is null
297: * @throws IOException
298: * if an I/O error occurs
299: */
300: public static char[] toCharArray(Reader input) throws IOException {
301: CharArrayWriter sw = new CharArrayWriter();
302: copy(input, sw);
303: return sw.toCharArray();
304: }
305:
306: // read toString
307: // -----------------------------------------------------------------------
308: /**
309: * Get the contents of an <code>InputStream</code> as a String using the
310: * default character encoding of the platform.
311: * <p>
312: * This method buffers the input internally, so there is no need to use a
313: * <code>BufferedInputStream</code>.
314: *
315: * @param input
316: * the <code>InputStream</code> to read from
317: * @return the requested String
318: * @throws NullPointerException
319: * if the input is null
320: * @throws IOException
321: * if an I/O error occurs
322: */
323: public static String toString(InputStream input) throws IOException {
324: StringWriter sw = new StringWriter();
325: copy(input, sw);
326: return sw.toString();
327: }
328:
329: /**
330: * Get the contents of an <code>InputStream</code> as a String using the
331: * specified character encoding.
332: * <p>
333: * Character encoding names can be found at <a
334: * href="http://www.iana.org/assignments/character-sets">IANA</a>.
335: * <p>
336: * This method buffers the input internally, so there is no need to use a
337: * <code>BufferedInputStream</code>.
338: *
339: * @param input
340: * the <code>InputStream</code> to read from
341: * @param encoding
342: * the encoding to use, null means platform default
343: * @return the requested String
344: * @throws NullPointerException
345: * if the input is null
346: * @throws IOException
347: * if an I/O error occurs
348: */
349: public static String toString(InputStream input, String encoding)
350: throws IOException {
351: StringWriter sw = new StringWriter();
352: copy(input, sw, encoding);
353: return sw.toString();
354: }
355:
356: /**
357: * Get the contents of a <code>Reader</code> as a String.
358: * <p>
359: * This method buffers the input internally, so there is no need to use a
360: * <code>BufferedReader</code>.
361: *
362: * @param input
363: * the <code>Reader</code> to read from
364: * @return the requested String
365: * @throws NullPointerException
366: * if the input is null
367: * @throws IOException
368: * if an I/O error occurs
369: */
370: public static String toString(Reader input) throws IOException {
371: StringWriter sw = new StringWriter();
372: copy(input, sw);
373: return sw.toString();
374: }
375:
376: // write byte[]
377: // -----------------------------------------------------------------------
378: /**
379: * Writes bytes from a <code>byte[]</code> to an <code>OutputStream</code>.
380: *
381: * @param data
382: * the byte array to write, do not modify during output, null
383: * ignored
384: * @param output
385: * the <code>OutputStream</code> to write to
386: * @throws NullPointerException
387: * if output is null
388: * @throws IOException
389: * if an I/O error occurs
390: * @since 1.1
391: */
392: public static void write(byte[] data, OutputStream output)
393: throws IOException {
394: if (data != null) {
395: output.write(data);
396: }
397: }
398:
399: /**
400: * Writes bytes from a <code>byte[]</code> to chars on a
401: * <code>Writer</code> using the default character encoding of the
402: * platform.
403: * <p>
404: * This method uses {@link String#String(byte[])}.
405: *
406: * @param data
407: * the byte array to write, do not modify during output, null
408: * ignored
409: * @param output
410: * the <code>Writer</code> to write to
411: * @throws NullPointerException
412: * if output is null
413: * @throws IOException
414: * if an I/O error occurs
415: * @since 1.1
416: */
417: public static void write(byte[] data, Writer output)
418: throws IOException {
419: if (data != null) {
420: output.write(new String(data));
421: }
422: }
423:
424: /**
425: * Writes bytes from a <code>byte[]</code> to chars on a
426: * <code>Writer</code> using the specified character encoding.
427: * <p>
428: * Character encoding names can be found at <a
429: * href="http://www.iana.org/assignments/character-sets">IANA</a>.
430: * <p>
431: * This method uses {@link String#String(byte[], String)}.
432: *
433: * @param data
434: * the byte array to write, do not modify during output, null
435: * ignored
436: * @param output
437: * the <code>Writer</code> to write to
438: * @param encoding
439: * the encoding to use, null means platform default
440: * @throws NullPointerException
441: * if output is null
442: * @throws IOException
443: * if an I/O error occurs
444: * @since 1.1
445: */
446: public static void write(byte[] data, Writer output, String encoding)
447: throws IOException {
448: if (data != null) {
449: if (encoding == null) {
450: write(data, output);
451: } else {
452: output.write(new String(data, encoding));
453: }
454: }
455: }
456:
457: // write char[]
458: // -----------------------------------------------------------------------
459: /**
460: * Writes chars from a <code>char[]</code> to a <code>Writer</code>
461: * using the default character encoding of the platform.
462: *
463: * @param data
464: * the char array to write, do not modify during output, null
465: * ignored
466: * @param output
467: * the <code>Writer</code> to write to
468: * @throws NullPointerException
469: * if output is null
470: * @throws IOException
471: * if an I/O error occurs
472: * @since 1.1
473: */
474: public static void write(char[] data, Writer output)
475: throws IOException {
476: if (data != null) {
477: output.write(data);
478: }
479: }
480:
481: /**
482: * Writes chars from a <code>char[]</code> to bytes on an
483: * <code>OutputStream</code>.
484: * <p>
485: * This method uses {@link String#String(char[])} and
486: * {@link String#getBytes()}.
487: *
488: * @param data
489: * the char array to write, do not modify during output, null
490: * ignored
491: * @param output
492: * the <code>OutputStream</code> to write to
493: * @throws NullPointerException
494: * if output is null
495: * @throws IOException
496: * if an I/O error occurs
497: * @since 1.1
498: */
499: public static void write(char[] data, OutputStream output)
500: throws IOException {
501: if (data != null) {
502: output.write(new String(data).getBytes());
503: }
504: }
505:
506: /**
507: * Writes chars from a <code>char[]</code> to bytes on an
508: * <code>OutputStream</code> using the specified character encoding.
509: * <p>
510: * Character encoding names can be found at <a
511: * href="http://www.iana.org/assignments/character-sets">IANA</a>.
512: * <p>
513: * This method uses {@link String#String(char[])} and
514: * {@link String#getBytes(String)}.
515: *
516: * @param data
517: * the char array to write, do not modify during output, null
518: * ignored
519: * @param output
520: * the <code>OutputStream</code> to write to
521: * @param encoding
522: * the encoding to use, null means platform default
523: * @throws NullPointerException
524: * if output is null
525: * @throws IOException
526: * if an I/O error occurs
527: * @since 1.1
528: */
529: public static void write(char[] data, OutputStream output,
530: String encoding) throws IOException {
531: if (data != null) {
532: if (encoding == null) {
533: write(data, output);
534: } else {
535: output.write(new String(data).getBytes(encoding));
536: }
537: }
538: }
539:
540: // write String
541: // -----------------------------------------------------------------------
542: /**
543: * Writes chars from a <code>String</code> to a <code>Writer</code>.
544: *
545: * @param data
546: * the <code>String</code> to write, null ignored
547: * @param output
548: * the <code>Writer</code> to write to
549: * @throws NullPointerException
550: * if output is null
551: * @throws IOException
552: * if an I/O error occurs
553: * @since 1.1
554: */
555: public static void write(String data, Writer output)
556: throws IOException {
557: if (data != null) {
558: output.write(data);
559: }
560: }
561:
562: /**
563: * Writes chars from a <code>String</code> to bytes on an
564: * <code>OutputStream</code> using the default character encoding of the
565: * platform.
566: * <p>
567: * This method uses {@link String#getBytes()}.
568: *
569: * @param data
570: * the <code>String</code> to write, null ignored
571: * @param output
572: * the <code>OutputStream</code> to write to
573: * @throws NullPointerException
574: * if output is null
575: * @throws IOException
576: * if an I/O error occurs
577: * @since 1.1
578: */
579: public static void write(String data, OutputStream output)
580: throws IOException {
581: if (data != null) {
582: output.write(data.getBytes());
583: }
584: }
585:
586: /**
587: * Writes chars from a <code>String</code> to bytes on an
588: * <code>OutputStream</code> using the specified character encoding.
589: * <p>
590: * Character encoding names can be found at <a
591: * href="http://www.iana.org/assignments/character-sets">IANA</a>.
592: * <p>
593: * This method uses {@link String#getBytes(String)}.
594: *
595: * @param data
596: * the <code>String</code> to write, null ignored
597: * @param output
598: * the <code>OutputStream</code> to write to
599: * @param encoding
600: * the encoding to use, null means platform default
601: * @throws NullPointerException
602: * if output is null
603: * @throws IOException
604: * if an I/O error occurs
605: * @since 1.1
606: */
607: public static void write(String data, OutputStream output,
608: String encoding) throws IOException {
609: if (data != null) {
610: if (encoding == null) {
611: write(data, output);
612: } else {
613: output.write(data.getBytes(encoding));
614: }
615: }
616: }
617:
618: // write AppendingStringBuffer
619: // -----------------------------------------------------------------------
620: /**
621: * Writes chars from a <code>AppendingStringBuffer</code> to a
622: * <code>Writer</code>.
623: *
624: * @param data
625: * the <code>AppendingStringBuffer</code> to write, null
626: * ignored
627: * @param output
628: * the <code>Writer</code> to write to
629: * @throws NullPointerException
630: * if output is null
631: * @throws IOException
632: * if an I/O error occurs
633: * @since 1.1
634: */
635: public static void write(StringBuffer data, Writer output)
636: throws IOException {
637: if (data != null) {
638: output.write(data.toString());
639: }
640: }
641:
642: /**
643: * Writes chars from a <code>AppendingStringBuffer</code> to bytes on an
644: * <code>OutputStream</code> using the default character encoding of the
645: * platform.
646: * <p>
647: * This method uses {@link String#getBytes()}.
648: *
649: * @param data
650: * the <code>AppendingStringBuffer</code> to write, null
651: * ignored
652: * @param output
653: * the <code>OutputStream</code> to write to
654: * @throws NullPointerException
655: * if output is null
656: * @throws IOException
657: * if an I/O error occurs
658: * @since 1.1
659: */
660: public static void write(StringBuffer data, OutputStream output)
661: throws IOException {
662: if (data != null) {
663: output.write(data.toString().getBytes());
664: }
665: }
666:
667: /**
668: * Writes chars from a <code>AppendingStringBuffer</code> to bytes on an
669: * <code>OutputStream</code> using the specified character encoding.
670: * <p>
671: * Character encoding names can be found at <a
672: * href="http://www.iana.org/assignments/character-sets">IANA</a>.
673: * <p>
674: * This method uses {@link String#getBytes(String)}.
675: *
676: * @param data
677: * the <code>AppendingStringBuffer</code> to write, null
678: * ignored
679: * @param output
680: * the <code>OutputStream</code> to write to
681: * @param encoding
682: * the encoding to use, null means platform default
683: * @throws NullPointerException
684: * if output is null
685: * @throws IOException
686: * if an I/O error occurs
687: * @since 1.1
688: */
689: public static void write(StringBuffer data, OutputStream output,
690: String encoding) throws IOException {
691: if (data != null) {
692: if (encoding == null) {
693: write(data, output);
694: } else {
695: output.write(data.toString().getBytes(encoding));
696: }
697: }
698: }
699:
700: // copy from InputStream
701: // -----------------------------------------------------------------------
702: /**
703: * Copy bytes from an <code>InputStream</code> to an
704: * <code>OutputStream</code>.
705: * <p>
706: * This method buffers the input internally, so there is no need to use a
707: * <code>BufferedInputStream</code>.
708: *
709: * @param input
710: * the <code>InputStream</code> to read from
711: * @param output
712: * the <code>OutputStream</code> to write to
713: * @return the number of bytes copied
714: * @throws NullPointerException
715: * if the input or output is null
716: * @throws IOException
717: * if an I/O error occurs
718: * @since 1.1
719: */
720: public static int copy(InputStream input, OutputStream output)
721: throws IOException {
722: byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
723: int count = 0;
724: int n = 0;
725: while (-1 != (n = input.read(buffer))) {
726: output.write(buffer, 0, n);
727: count += n;
728: }
729: return count;
730: }
731:
732: /**
733: * Copy bytes from an <code>InputStream</code> to chars on a
734: * <code>Writer</code> using the default character encoding of the
735: * platform.
736: * <p>
737: * This method buffers the input internally, so there is no need to use a
738: * <code>BufferedInputStream</code>.
739: * <p>
740: * This method uses {@link InputStreamReader}.
741: *
742: * @param input
743: * the <code>InputStream</code> to read from
744: * @param output
745: * the <code>Writer</code> to write to
746: * @throws NullPointerException
747: * if the input or output is null
748: * @throws IOException
749: * if an I/O error occurs
750: * @since 1.1
751: */
752: public static void copy(InputStream input, Writer output)
753: throws IOException {
754: InputStreamReader in = new InputStreamReader(input);
755: copy(in, output);
756: }
757:
758: /**
759: * Copy bytes from an <code>InputStream</code> to chars on a
760: * <code>Writer</code> using the specified character encoding.
761: * <p>
762: * This method buffers the input internally, so there is no need to use a
763: * <code>BufferedInputStream</code>.
764: * <p>
765: * Character encoding names can be found at <a
766: * href="http://www.iana.org/assignments/character-sets">IANA</a>.
767: * <p>
768: * This method uses {@link InputStreamReader}.
769: *
770: * @param input
771: * the <code>InputStream</code> to read from
772: * @param output
773: * the <code>Writer</code> to write to
774: * @param encoding
775: * the encoding to use, null means platform default
776: * @throws NullPointerException
777: * if the input or output is null
778: * @throws IOException
779: * if an I/O error occurs
780: * @since 1.1
781: */
782: public static void copy(InputStream input, Writer output,
783: String encoding) throws IOException {
784: if (encoding == null) {
785: copy(input, output);
786: } else {
787: InputStreamReader in = new InputStreamReader(input,
788: encoding);
789: copy(in, output);
790: }
791: }
792:
793: // copy from Reader
794: // -----------------------------------------------------------------------
795: /**
796: * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
797: * <p>
798: * This method buffers the input internally, so there is no need to use a
799: * <code>BufferedReader</code>.
800: *
801: * @param input
802: * the <code>Reader</code> to read from
803: * @param output
804: * the <code>Writer</code> to write to
805: * @return the number of characters copied
806: * @throws NullPointerException
807: * if the input or output is null
808: * @throws IOException
809: * if an I/O error occurs
810: * @since 1.1
811: */
812: public static int copy(Reader input, Writer output)
813: throws IOException {
814: char[] buffer = new char[DEFAULT_BUFFER_SIZE];
815: int count = 0;
816: int n = 0;
817: while (-1 != (n = input.read(buffer))) {
818: output.write(buffer, 0, n);
819: count += n;
820: }
821: return count;
822: }
823:
824: /**
825: * Copy chars from a <code>Reader</code> to bytes on an
826: * <code>OutputStream</code> using the default character encoding of the
827: * platform, and calling flush.
828: * <p>
829: * This method buffers the input internally, so there is no need to use a
830: * <code>BufferedReader</code>.
831: * <p>
832: * Due to the implementation of OutputStreamWriter, this method performs a
833: * flush.
834: * <p>
835: * This method uses {@link OutputStreamWriter}.
836: *
837: * @param input
838: * the <code>Reader</code> to read from
839: * @param output
840: * the <code>OutputStream</code> to write to
841: * @throws NullPointerException
842: * if the input or output is null
843: * @throws IOException
844: * if an I/O error occurs
845: * @since 1.1
846: */
847: public static void copy(Reader input, OutputStream output)
848: throws IOException {
849: OutputStreamWriter out = new OutputStreamWriter(output);
850: copy(input, out);
851: out.flush();
852: }
853:
854: /**
855: * Copy chars from a <code>Reader</code> to bytes on an
856: * <code>OutputStream</code> using the specified character encoding, and
857: * calling flush.
858: * <p>
859: * This method buffers the input internally, so there is no need to use a
860: * <code>BufferedReader</code>.
861: * <p>
862: * Character encoding names can be found at <a
863: * href="http://www.iana.org/assignments/character-sets">IANA</a>.
864: * <p>
865: * Due to the implementation of OutputStreamWriter, this method performs a
866: * flush.
867: * <p>
868: * This method uses {@link OutputStreamWriter}.
869: *
870: * @param input
871: * the <code>Reader</code> to read from
872: * @param output
873: * the <code>OutputStream</code> to write to
874: * @param encoding
875: * the encoding to use, null means platform default
876: * @throws NullPointerException
877: * if the input or output is null
878: * @throws IOException
879: * if an I/O error occurs
880: * @since 1.1
881: */
882: public static void copy(Reader input, OutputStream output,
883: String encoding) throws IOException {
884: if (encoding == null) {
885: copy(input, output);
886: } else {
887: OutputStreamWriter out = new OutputStreamWriter(output,
888: encoding);
889: copy(input, out);
890: out.flush();
891: }
892: }
893:
894: // content equals
895: // -----------------------------------------------------------------------
896: /**
897: * Compare the contents of two Streams to determine if they are equal or
898: * not.
899: * <p>
900: * This method buffers the input internally using
901: * <code>BufferedInputStream</code> if they are not already buffered.
902: *
903: * @param input1
904: * the first stream
905: * @param input2
906: * the second stream
907: * @return true if the content of the streams are equal or they both don't
908: * exist, false otherwise
909: * @throws NullPointerException
910: * if either input is null
911: * @throws IOException
912: * if an I/O error occurs
913: */
914: public static boolean contentEquals(InputStream input1,
915: InputStream input2) throws IOException {
916: if (!(input1 instanceof BufferedInputStream)) {
917: input1 = new BufferedInputStream(input1);
918: }
919: if (!(input2 instanceof BufferedInputStream)) {
920: input2 = new BufferedInputStream(input2);
921: }
922:
923: int ch = input1.read();
924: while (-1 != ch) {
925: int ch2 = input2.read();
926: if (ch != ch2) {
927: return false;
928: }
929: ch = input1.read();
930: }
931:
932: int ch2 = input2.read();
933: return (ch2 == -1);
934: }
935:
936: /**
937: * Compare the contents of two Readers to determine if they are equal or
938: * not.
939: * <p>
940: * This method buffers the input internally using
941: * <code>BufferedReader</code> if they are not already buffered.
942: *
943: * @param input1
944: * the first reader
945: * @param input2
946: * the second reader
947: * @return true if the content of the readers are equal or they both don't
948: * exist, false otherwise
949: * @throws NullPointerException
950: * if either input is null
951: * @throws IOException
952: * if an I/O error occurs
953: * @since 1.1
954: */
955: public static boolean contentEquals(Reader input1, Reader input2)
956: throws IOException {
957: if (!(input1 instanceof BufferedReader)) {
958: input1 = new BufferedReader(input1);
959: }
960: if (!(input2 instanceof BufferedReader)) {
961: input2 = new BufferedReader(input2);
962: }
963:
964: int ch = input1.read();
965: while (-1 != ch) {
966: int ch2 = input2.read();
967: if (ch != ch2) {
968: return false;
969: }
970: ch = input1.read();
971: }
972:
973: int ch2 = input2.read();
974: return (ch2 == -1);
975: }
976:
977: }
|