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  
  * @version $Id: CopyUtils.java 1563227 2014-01-31 19:45:30Z ggregory $
 107  
  * @deprecated Use IOUtils. Will be removed in 2.0.
 108  
  *  Methods renamed to IOUtils.write() or IOUtils.copy().
 109  
  *  Null handling behaviour changed in IOUtils (null data does not
 110  
  *  throw NullPointerException).
 111  
  */
 112  
 @Deprecated
 113  
 public class CopyUtils {
 114  
 
 115  
     /**
 116  
      * The default size of the buffer.
 117  
      */
 118  
     private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
 119  
 
 120  
     /**
 121  
      * Instances should NOT be constructed in standard programming.
 122  
      */
 123  2
     public CopyUtils() { }
 124  
 
 125  
     // ----------------------------------------------------------------
 126  
     // byte[] -> OutputStream
 127  
     // ----------------------------------------------------------------
 128  
 
 129  
     /**
 130  
      * Copy bytes from a <code>byte[]</code> to an <code>OutputStream</code>.
 131  
      * @param input the byte array to read from
 132  
      * @param output the <code>OutputStream</code> to write to
 133  
      * @throws IOException In case of an I/O problem
 134  
      */
 135  
     public static void copy(final byte[] input, final OutputStream output)
 136  
             throws IOException {
 137  4
         output.write(input);
 138  4
     }
 139  
 
 140  
     // ----------------------------------------------------------------
 141  
     // byte[] -> Writer
 142  
     // ----------------------------------------------------------------
 143  
 
 144  
     /**
 145  
      * Copy and convert bytes from a <code>byte[]</code> to chars on a
 146  
      * <code>Writer</code>.
 147  
      * The platform's default encoding is used for the byte-to-char conversion.
 148  
      * @param input the byte array to read from
 149  
      * @param output the <code>Writer</code> to write to
 150  
      * @throws IOException In case of an I/O problem
 151  
      * @deprecated 2.5 use {@link #copy(byte[], Writer, String)} instead
 152  
      */
 153  
     @Deprecated
 154  
     public static void copy(final byte[] input, final Writer output)
 155  
             throws IOException {
 156  4
         final ByteArrayInputStream in = new ByteArrayInputStream(input);
 157  4
         copy(in, output);
 158  4
     }
 159  
 
 160  
 
 161  
     /**
 162  
      * Copy and convert bytes from a <code>byte[]</code> to chars on a
 163  
      * <code>Writer</code>, using the specified encoding.
 164  
      * @param input the byte array to read from
 165  
      * @param output the <code>Writer</code> to write to
 166  
      * @param encoding The name of a supported character encoding. See the
 167  
      * <a href="http://www.iana.org/assignments/character-sets">IANA
 168  
      * Charset Registry</a> for a list of valid encoding types.
 169  
      * @throws IOException In case of an I/O problem
 170  
      */
 171  
     public static void copy(
 172  
             final byte[] input,
 173  
             final Writer output,
 174  
             final String encoding)
 175  
                 throws IOException {
 176  2
         final ByteArrayInputStream in = new ByteArrayInputStream(input);
 177  2
         copy(in, output, encoding);
 178  2
     }
 179  
 
 180  
 
 181  
     // ----------------------------------------------------------------
 182  
     // Core copy methods
 183  
     // ----------------------------------------------------------------
 184  
 
 185  
     /**
 186  
      * Copy bytes from an <code>InputStream</code> to an
 187  
      * <code>OutputStream</code>.
 188  
      * @param input the <code>InputStream</code> to read from
 189  
      * @param output the <code>OutputStream</code> to write to
 190  
      * @return the number of bytes copied
 191  
      * @throws IOException In case of an I/O problem
 192  
      */
 193  
     public static int copy(
 194  
             final InputStream input,
 195  
             final OutputStream output)
 196  
                 throws IOException {
 197  2
         final byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
 198  2
         int count = 0;
 199  2
         int n = 0;
 200  6
         while (-1 != (n = input.read(buffer))) {
 201  4
             output.write(buffer, 0, n);
 202  4
             count += n;
 203  
         }
 204  2
         return count;
 205  
     }
 206  
 
 207  
     // ----------------------------------------------------------------
 208  
     // Reader -> Writer
 209  
     // ----------------------------------------------------------------
 210  
 
 211  
     /**
 212  
      * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
 213  
      * @param input the <code>Reader</code> to read from
 214  
      * @param output the <code>Writer</code> to write to
 215  
      * @return the number of characters copied
 216  
      * @throws IOException In case of an I/O problem
 217  
      */
 218  
     public static int copy(
 219  
             final Reader input,
 220  
             final Writer output)
 221  
                 throws IOException {
 222  18
         final char[] buffer = new char[DEFAULT_BUFFER_SIZE];
 223  18
         int count = 0;
 224  18
         int n = 0;
 225  50
         while (-1 != (n = input.read(buffer))) {
 226  32
             output.write(buffer, 0, n);
 227  32
             count += n;
 228  
         }
 229  18
         return count;
 230  
     }
 231  
 
 232  
     // ----------------------------------------------------------------
 233  
     // InputStream -> Writer
 234  
     // ----------------------------------------------------------------
 235  
 
 236  
     /**
 237  
      * Copy and convert bytes from an <code>InputStream</code> to chars on a
 238  
      * <code>Writer</code>.
 239  
      * The platform's default encoding is used for the byte-to-char conversion.
 240  
      * @param input the <code>InputStream</code> to read from
 241  
      * @param output the <code>Writer</code> to write to
 242  
      * @throws IOException In case of an I/O problem
 243  
      * @deprecated 2.5 use {@link #copy(InputStream, Writer, String)} instead
 244  
      */
 245  
     @Deprecated
 246  
     public static void copy(
 247  
             final InputStream input,
 248  
             final Writer output)
 249  
                 throws IOException {
 250  
         // make explicit the dependency on the default encoding
 251  6
         final InputStreamReader in = new InputStreamReader(input, Charset.defaultCharset());
 252  6
         copy(in, output);
 253  6
     }
 254  
 
 255  
     /**
 256  
      * Copy and convert bytes from an <code>InputStream</code> to chars on a
 257  
      * <code>Writer</code>, using the specified encoding.
 258  
      * @param input the <code>InputStream</code> to read from
 259  
      * @param output the <code>Writer</code> to write to
 260  
      * @param encoding The name of a supported character encoding. See the
 261  
      * <a href="http://www.iana.org/assignments/character-sets">IANA
 262  
      * Charset Registry</a> for a list of valid encoding types.
 263  
      * @throws IOException In case of an I/O problem
 264  
      */
 265  
     public static void copy(
 266  
             final InputStream input,
 267  
             final Writer output,
 268  
             final String encoding)
 269  
                 throws IOException {
 270  4
         final InputStreamReader in = new InputStreamReader(input, encoding);
 271  4
         copy(in, output);
 272  4
     }
 273  
 
 274  
 
 275  
     // ----------------------------------------------------------------
 276  
     // Reader -> OutputStream
 277  
     // ----------------------------------------------------------------
 278  
 
 279  
     /**
 280  
      * Serialize chars from a <code>Reader</code> to bytes on an
 281  
      * <code>OutputStream</code>, and flush the <code>OutputStream</code>.
 282  
      * Uses the default platform encoding.
 283  
      * @param input the <code>Reader</code> to read from
 284  
      * @param output the <code>OutputStream</code> to write to
 285  
      * @throws IOException In case of an I/O problem
 286  
      * @deprecated 2.5 use {@link #copy(Reader, OutputStream, String)} instead
 287  
      */
 288  
     @Deprecated
 289  
     public static void copy(
 290  
             final Reader input,
 291  
             final OutputStream output)
 292  
                 throws IOException {
 293  
         // make explicit the dependency on the default encoding
 294  2
         final OutputStreamWriter out = new OutputStreamWriter(output, Charset.defaultCharset());
 295  2
         copy(input, out);
 296  
         // XXX Unless anyone is planning on rewriting OutputStreamWriter, we
 297  
         // have to flush here.
 298  2
         out.flush();
 299  2
     }
 300  
 
 301  
     /**
 302  
      * Serialize chars from a <code>Reader</code> to bytes on an
 303  
      * <code>OutputStream</code>, and flush the <code>OutputStream</code>.
 304  
      * @param input the <code>Reader</code> to read from
 305  
      * @param output the <code>OutputStream</code> to write to
 306  
      * @throws IOException In case of an I/O problem
 307  
      * @since 2.5
 308  
      */
 309  
     public static void copy(
 310  
             final Reader input,
 311  
             final OutputStream output,
 312  
             final String encoding)
 313  
                 throws IOException {
 314  0
         final OutputStreamWriter out = new OutputStreamWriter(output, encoding);
 315  0
         copy(input, out);
 316  
         // XXX Unless anyone is planning on rewriting OutputStreamWriter, we
 317  
         // have to flush here.
 318  0
         out.flush();
 319  0
     }
 320  
 
 321  
     // ----------------------------------------------------------------
 322  
     // String -> OutputStream
 323  
     // ----------------------------------------------------------------
 324  
 
 325  
     /**
 326  
      * Serialize chars from a <code>String</code> to bytes on an
 327  
      * <code>OutputStream</code>, and
 328  
      * flush the <code>OutputStream</code>.
 329  
      * Uses the platform default encoding.
 330  
      * @param input the <code>String</code> to read from
 331  
      * @param output the <code>OutputStream</code> to write to
 332  
      * @throws IOException In case of an I/O problem
 333  
      * @deprecated 2.5 use {@link #copy(String, OutputStream, String)} instead
 334  
      */
 335  
     @Deprecated
 336  
     public static void copy(
 337  
             final String input,
 338  
             final OutputStream output)
 339  
                 throws IOException {
 340  4
         final StringReader in = new StringReader(input);
 341  
         // make explicit the dependency on the default encoding
 342  4
         final OutputStreamWriter out = new OutputStreamWriter(output, Charset.defaultCharset());
 343  4
         copy(in, out);
 344  
         // XXX Unless anyone is planning on rewriting OutputStreamWriter, we
 345  
         // have to flush here.
 346  4
         out.flush();
 347  4
     }
 348  
 
 349  
     /**
 350  
      * Serialize chars from a <code>String</code> to bytes on an
 351  
      * <code>OutputStream</code>, and
 352  
      * flush the <code>OutputStream</code>.
 353  
      * @param input the <code>String</code> to read from
 354  
      * @param output the <code>OutputStream</code> to write to
 355  
      * @throws IOException In case of an I/O problem
 356  
      * @since 2.5
 357  
      */
 358  
     public static void copy(
 359  
             final String input,
 360  
             final OutputStream output,
 361  
             final String encoding)
 362  
                 throws IOException {
 363  0
         final StringReader in = new StringReader(input);
 364  0
         final OutputStreamWriter out = new OutputStreamWriter(output, encoding);
 365  0
         copy(in, out);
 366  
         // XXX Unless anyone is planning on rewriting OutputStreamWriter, we
 367  
         // have to flush here.
 368  0
         out.flush();
 369  0
     }
 370  
 
 371  
     // ----------------------------------------------------------------
 372  
     // String -> Writer
 373  
     // ----------------------------------------------------------------
 374  
 
 375  
     /**
 376  
      * Copy chars from a <code>String</code> to a <code>Writer</code>.
 377  
      * @param input the <code>String</code> to read from
 378  
      * @param output the <code>Writer</code> to write to
 379  
      * @throws IOException In case of an I/O problem
 380  
      */
 381  
     public static void copy(final String input, final Writer output)
 382  
                 throws IOException {
 383  4
         output.write(input);
 384  4
     }
 385  
 
 386  
 }