Coverage Report - org.apache.commons.io.CopyUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
CopyUtils
81%
40/49
100%
4/4
1,154
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  * 
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  * 
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.apache.commons.io;
 18  
 
 19  
 import java.io.ByteArrayInputStream;
 20  
 import java.io.IOException;
 21  
 import java.io.InputStream;
 22  
 import java.io.InputStreamReader;
 23  
 import java.io.OutputStream;
 24  
 import java.io.OutputStreamWriter;
 25  
 import java.io.Reader;
 26  
 import java.io.StringReader;
 27  
 import java.io.Writer;
 28  
 import java.nio.charset.Charset;
 29  
 
 30  
 /**
 31  
  * This class provides static utility methods for buffered
 32  
  * copying between sources (<code>InputStream</code>, <code>Reader</code>,
 33  
  * <code>String</code> and <code>byte[]</code>) and destinations
 34  
  * (<code>OutputStream</code>, <code>Writer</code>, <code>String</code> and
 35  
  * <code>byte[]</code>).
 36  
  * <p>
 37  
  * Unless otherwise noted, these <code>copy</code> methods do <em>not</em>
 38  
  * flush or close the streams. Often doing so would require making non-portable
 39  
  * assumptions about the streams' origin and further use. This means that both
 40  
  * streams' <code>close()</code> methods must be called after copying. if one
 41  
  * omits this step, then the stream resources (sockets, file descriptors) are
 42  
  * released when the associated Stream is garbage-collected. It is not a good
 43  
  * idea to rely on this mechanism. For a good overview of the distinction
 44  
  * between "memory management" and "resource management", see
 45  
  * <a href="http://www.unixreview.com/articles/1998/9804/9804ja/ja.htm">this
 46  
  * UnixReview article</a>.
 47  
  * <p>
 48  
  * For byte-to-char methods, a <code>copy</code> variant allows the encoding
 49  
  * to be selected (otherwise the platform default is used). We would like to
 50  
  * encourage you to always specify the encoding because relying on the platform
 51  
  * default can lead to unexpected results.
 52  
  * <p>
 53  
  * We don't provide special variants for the <code>copy</code> methods that
 54  
  * let you specify the buffer size because in modern VMs the impact on speed
 55  
  * seems to be minimal. We're using a default buffer size of 4 KB.
 56  
  * <p>
 57  
  * The <code>copy</code> methods use an internal buffer when copying. It is
 58  
  * therefore advisable <em>not</em> to deliberately wrap the stream arguments
 59  
  * to the <code>copy</code> methods in <code>Buffered*</code> streams. For
 60  
  * example, don't do the following:
 61  
  * <pre>
 62  
  *  copy( new BufferedInputStream( in ), new BufferedOutputStream( out ) );
 63  
  *  </pre>
 64  
  * The rationale is as follows:
 65  
  * <p>
 66  
  * Imagine that an InputStream's read() is a very expensive operation, which
 67  
  * would usually suggest wrapping in a BufferedInputStream. The
 68  
  * BufferedInputStream works by issuing infrequent
 69  
  * {@link java.io.InputStream#read(byte[] b, int off, int len)} requests on the
 70  
  * underlying InputStream, to fill an internal buffer, from which further
 71  
  * <code>read</code> requests can inexpensively get their data (until the buffer
 72  
  * runs out).
 73  
  * <p>
 74  
  * However, the <code>copy</code> methods do the same thing, keeping an
 75  
  * internal buffer, populated by
 76  
  * {@link InputStream#read(byte[] b, int off, int len)} requests. Having two
 77  
  * buffers (or three if the destination stream is also buffered) is pointless,
 78  
  * and the unnecessary buffer management hurts performance slightly (about 3%,
 79  
  * according to some simple experiments).
 80  
  * <p>
 81  
  * Behold, intrepid explorers; a map of this class:
 82  
  * <pre>
 83  
  *       Method      Input               Output          Dependency
 84  
  *       ------      -----               ------          -------
 85  
  * 1     copy        InputStream         OutputStream    (primitive)
 86  
  * 2     copy        Reader              Writer          (primitive)
 87  
  *
 88  
  * 3     copy        InputStream         Writer          2
 89  
  *
 90  
  * 4     copy        Reader              OutputStream    2
 91  
  *
 92  
  * 5     copy        String              OutputStream    2
 93  
  * 6     copy        String              Writer          (trivial)
 94  
  *
 95  
  * 7     copy        byte[]              Writer          3
 96  
  * 8     copy        byte[]              OutputStream    (trivial)
 97  
  * </pre>
 98  
  * <p>
 99  
  * Note that only the first two methods shuffle bytes; the rest use these
 100  
  * two, or (if possible) copy using native Java copy methods. As there are
 101  
  * method variants to specify the encoding, each row may
 102  
  * correspond to up to 2 methods.
 103  
  * <p>
 104  
  * Origin of code: Excalibur.
 105  
  *
 106  
  * @deprecated Use IOUtils. Will be removed in 2.0.
 107  
  *  Methods renamed to IOUtils.write() or IOUtils.copy().
 108  
  *  Null handling behaviour changed in IOUtils (null data does not
 109  
  *  throw NullPointerException).
 110  
  */
 111  
 @Deprecated
 112  
 public class CopyUtils {
 113  
 
 114  
     /**
 115  
      * The default size of the buffer.
 116  
      */
 117  
     private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
 118  
 
 119  
     /**
 120  
      * Instances should NOT be constructed in standard programming.
 121  
      */
 122  2
     public CopyUtils() { }
 123  
 
 124  
     // ----------------------------------------------------------------
 125  
     // byte[] -> OutputStream
 126  
     // ----------------------------------------------------------------
 127  
 
 128  
     /**
 129  
      * Copy bytes from a <code>byte[]</code> to an <code>OutputStream</code>.
 130  
      * @param input the byte array to read from
 131  
      * @param output the <code>OutputStream</code> to write to
 132  
      * @throws IOException In case of an I/O problem
 133  
      */
 134  
     public static void copy(final byte[] input, final OutputStream output)
 135  
             throws IOException {
 136  4
         output.write(input);
 137  4
     }
 138  
 
 139  
     // ----------------------------------------------------------------
 140  
     // byte[] -> Writer
 141  
     // ----------------------------------------------------------------
 142  
 
 143  
     /**
 144  
      * Copy and convert bytes from a <code>byte[]</code> to chars on a
 145  
      * <code>Writer</code>.
 146  
      * The platform's default encoding is used for the byte-to-char conversion.
 147  
      * @param input the byte array to read from
 148  
      * @param output the <code>Writer</code> to write to
 149  
      * @throws IOException In case of an I/O problem
 150  
      * @deprecated 2.5 use {@link #copy(byte[], Writer, String)} instead
 151  
      */
 152  
     @Deprecated
 153  
     public static void copy(final byte[] input, final Writer output)
 154  
             throws IOException {
 155  4
         final ByteArrayInputStream in = new ByteArrayInputStream(input);
 156  4
         copy(in, output);
 157  4
     }
 158  
 
 159  
 
 160  
     /**
 161  
      * Copy and convert bytes from a <code>byte[]</code> to chars on a
 162  
      * <code>Writer</code>, using the specified encoding.
 163  
      * @param input the byte array to read from
 164  
      * @param output the <code>Writer</code> to write to
 165  
      * @param encoding The name of a supported character encoding. See the
 166  
      * <a href="http://www.iana.org/assignments/character-sets">IANA
 167  
      * Charset Registry</a> for a list of valid encoding types.
 168  
      * @throws IOException In case of an I/O problem
 169  
      */
 170  
     public static void copy(
 171  
             final byte[] input,
 172  
             final Writer output,
 173  
             final String encoding)
 174  
                 throws IOException {
 175  2
         final ByteArrayInputStream in = new ByteArrayInputStream(input);
 176  2
         copy(in, output, encoding);
 177  2
     }
 178  
 
 179  
 
 180  
     // ----------------------------------------------------------------
 181  
     // Core copy methods
 182  
     // ----------------------------------------------------------------
 183  
 
 184  
     /**
 185  
      * Copy bytes from an <code>InputStream</code> to an
 186  
      * <code>OutputStream</code>.
 187  
      * @param input the <code>InputStream</code> to read from
 188  
      * @param output the <code>OutputStream</code> to write to
 189  
      * @return the number of bytes copied
 190  
      * @throws IOException In case of an I/O problem
 191  
      */
 192  
     public static int copy(
 193  
             final InputStream input,
 194  
             final OutputStream output)
 195  
                 throws IOException {
 196  2
         final byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
 197  2
         int count = 0;
 198  2
         int n = 0;
 199  6
         while (-1 != (n = input.read(buffer))) {
 200  4
             output.write(buffer, 0, n);
 201  4
             count += n;
 202  
         }
 203  2
         return count;
 204  
     }
 205  
 
 206  
     // ----------------------------------------------------------------
 207  
     // Reader -> Writer
 208  
     // ----------------------------------------------------------------
 209  
 
 210  
     /**
 211  
      * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
 212  
      * @param input the <code>Reader</code> to read from
 213  
      * @param output the <code>Writer</code> to write to
 214  
      * @return the number of characters copied
 215  
      * @throws IOException In case of an I/O problem
 216  
      */
 217  
     public static int copy(
 218  
             final Reader input,
 219  
             final Writer output)
 220  
                 throws IOException {
 221  18
         final char[] buffer = new char[DEFAULT_BUFFER_SIZE];
 222  18
         int count = 0;
 223  18
         int n = 0;
 224  50
         while (-1 != (n = input.read(buffer))) {
 225  32
             output.write(buffer, 0, n);
 226  32
             count += n;
 227  
         }
 228  18
         return count;
 229  
     }
 230  
 
 231  
     // ----------------------------------------------------------------
 232  
     // InputStream -> Writer
 233  
     // ----------------------------------------------------------------
 234  
 
 235  
     /**
 236  
      * Copy and convert bytes from an <code>InputStream</code> to chars on a
 237  
      * <code>Writer</code>.
 238  
      * The platform's default encoding is used for the byte-to-char conversion.
 239  
      * @param input the <code>InputStream</code> to read from
 240  
      * @param output the <code>Writer</code> to write to
 241  
      * @throws IOException In case of an I/O problem
 242  
      * @deprecated 2.5 use {@link #copy(InputStream, Writer, String)} instead
 243  
      */
 244  
     @Deprecated
 245  
     public static void copy(
 246  
             final InputStream input,
 247  
             final Writer output)
 248  
                 throws IOException {
 249  
         // make explicit the dependency on the default encoding
 250  6
         final InputStreamReader in = new InputStreamReader(input, Charset.defaultCharset());
 251  6
         copy(in, output);
 252  6
     }
 253  
 
 254  
     /**
 255  
      * Copy and convert bytes from an <code>InputStream</code> to chars on a
 256  
      * <code>Writer</code>, using the specified encoding.
 257  
      * @param input the <code>InputStream</code> to read from
 258  
      * @param output the <code>Writer</code> to write to
 259  
      * @param encoding The name of a supported character encoding. See the
 260  
      * <a href="http://www.iana.org/assignments/character-sets">IANA
 261  
      * Charset Registry</a> for a list of valid encoding types.
 262  
      * @throws IOException In case of an I/O problem
 263  
      */
 264  
     public static void copy(
 265  
             final InputStream input,
 266  
             final Writer output,
 267  
             final String encoding)
 268  
                 throws IOException {
 269  4
         final InputStreamReader in = new InputStreamReader(input, encoding);
 270  4
         copy(in, output);
 271  4
     }
 272  
 
 273  
 
 274  
     // ----------------------------------------------------------------
 275  
     // Reader -> OutputStream
 276  
     // ----------------------------------------------------------------
 277  
 
 278  
     /**
 279  
      * Serialize chars from a <code>Reader</code> to bytes on an
 280  
      * <code>OutputStream</code>, and flush the <code>OutputStream</code>.
 281  
      * Uses the default platform encoding.
 282  
      * @param input the <code>Reader</code> to read from
 283  
      * @param output the <code>OutputStream</code> to write to
 284  
      * @throws IOException In case of an I/O problem
 285  
      * @deprecated 2.5 use {@link #copy(Reader, OutputStream, String)} instead
 286  
      */
 287  
     @Deprecated
 288  
     public static void copy(
 289  
             final Reader input,
 290  
             final OutputStream output)
 291  
                 throws IOException {
 292  
         // make explicit the dependency on the default encoding
 293  2
         final OutputStreamWriter out = new OutputStreamWriter(output, Charset.defaultCharset());
 294  2
         copy(input, out);
 295  
         // XXX Unless anyone is planning on rewriting OutputStreamWriter, we
 296  
         // have to flush here.
 297  2
         out.flush();
 298  2
     }
 299  
 
 300  
     /**
 301  
      * Serialize chars from a <code>Reader</code> to bytes on an
 302  
      * <code>OutputStream</code>, and flush the <code>OutputStream</code>.
 303  
      * @param input the <code>Reader</code> to read from
 304  
      * @param output the <code>OutputStream</code> to write to
 305  
      * @param encoding The name of a supported character encoding. See the
 306  
      * <a href="http://www.iana.org/assignments/character-sets">IANA
 307  
      * Charset Registry</a> for a list of valid encoding types.
 308  
      * @throws IOException In case of an I/O problem
 309  
      * @since 2.5
 310  
      */
 311  
     public static void copy(
 312  
             final Reader input,
 313  
             final OutputStream output,
 314  
             final String encoding)
 315  
                 throws IOException {
 316  0
         final OutputStreamWriter out = new OutputStreamWriter(output, encoding);
 317  0
         copy(input, out);
 318  
         // XXX Unless anyone is planning on rewriting OutputStreamWriter, we
 319  
         // have to flush here.
 320  0
         out.flush();
 321  0
     }
 322  
 
 323  
     // ----------------------------------------------------------------
 324  
     // String -> OutputStream
 325  
     // ----------------------------------------------------------------
 326  
 
 327  
     /**
 328  
      * Serialize chars from a <code>String</code> to bytes on an
 329  
      * <code>OutputStream</code>, and
 330  
      * flush the <code>OutputStream</code>.
 331  
      * Uses the platform default encoding.
 332  
      * @param input the <code>String</code> to read from
 333  
      * @param output the <code>OutputStream</code> to write to
 334  
      * @throws IOException In case of an I/O problem
 335  
      * @deprecated 2.5 use {@link #copy(String, OutputStream, String)} instead
 336  
      */
 337  
     @Deprecated
 338  
     public static void copy(
 339  
             final String input,
 340  
             final OutputStream output)
 341  
                 throws IOException {
 342  4
         final StringReader in = new StringReader(input);
 343  
         // make explicit the dependency on the default encoding
 344  4
         final OutputStreamWriter out = new OutputStreamWriter(output, Charset.defaultCharset());
 345  4
         copy(in, out);
 346  
         // XXX Unless anyone is planning on rewriting OutputStreamWriter, we
 347  
         // have to flush here.
 348  4
         out.flush();
 349  4
     }
 350  
 
 351  
     /**
 352  
      * Serialize chars from a <code>String</code> to bytes on an
 353  
      * <code>OutputStream</code>, and
 354  
      * flush the <code>OutputStream</code>.
 355  
      * @param input the <code>String</code> to read from
 356  
      * @param output the <code>OutputStream</code> to write to
 357  
      * @param encoding The name of a supported character encoding. See the
 358  
      * <a href="http://www.iana.org/assignments/character-sets">IANA
 359  
      * Charset Registry</a> for a list of valid encoding types.
 360  
      * @throws IOException In case of an I/O problem
 361  
      * @since 2.5
 362  
      */
 363  
     public static void copy(
 364  
             final String input,
 365  
             final OutputStream output,
 366  
             final String encoding)
 367  
                 throws IOException {
 368  0
         final StringReader in = new StringReader(input);
 369  0
         final OutputStreamWriter out = new OutputStreamWriter(output, encoding);
 370  0
         copy(in, out);
 371  
         // XXX Unless anyone is planning on rewriting OutputStreamWriter, we
 372  
         // have to flush here.
 373  0
         out.flush();
 374  0
     }
 375  
 
 376  
     // ----------------------------------------------------------------
 377  
     // String -> Writer
 378  
     // ----------------------------------------------------------------
 379  
 
 380  
     /**
 381  
      * Copy chars from a <code>String</code> to a <code>Writer</code>.
 382  
      * @param input the <code>String</code> to read from
 383  
      * @param output the <code>Writer</code> to write to
 384  
      * @throws IOException In case of an I/O problem
 385  
      */
 386  
     public static void copy(final String input, final Writer output)
 387  
                 throws IOException {
 388  4
         output.write(input);
 389  4
     }
 390  
 
 391  
 }