Home | History | Annotate | Download | only in output
      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.output;
     18 
     19 import java.io.IOException;
     20 import java.io.OutputStream;
     21 
     22 /**
     23  * A decorating output stream that counts the number of bytes that have passed
     24  * through the stream so far.
     25  * <p>
     26  * A typical use case would be during debugging, to ensure that data is being
     27  * written as expected.
     28  *
     29  * @version $Id: CountingOutputStream.java 471628 2006-11-06 04:06:45Z bayard $
     30  */
     31 public class CountingOutputStream extends ProxyOutputStream {
     32 
     33     /** The count of bytes that have passed. */
     34     private long count;
     35 
     36     /**
     37      * Constructs a new CountingOutputStream.
     38      *
     39      * @param out  the OutputStream to write to
     40      */
     41     public CountingOutputStream( OutputStream out ) {
     42         super(out);
     43     }
     44 
     45     //-----------------------------------------------------------------------
     46     /**
     47      * Writes the contents of the specified byte array to this output stream
     48      * keeping count of the number of bytes written.
     49      *
     50      * @param b  the bytes to write, not null
     51      * @throws IOException if an I/O error occurs
     52      * @see java.io.OutputStream#write(byte[])
     53      */
     54     public void write(byte[] b) throws IOException {
     55         count += b.length;
     56         super.write(b);
     57     }
     58 
     59     /**
     60      * Writes a portion of the specified byte array to this output stream
     61      * keeping count of the number of bytes written.
     62      *
     63      * @param b  the bytes to write, not null
     64      * @param off  the start offset in the buffer
     65      * @param len  the maximum number of bytes to write
     66      * @throws IOException if an I/O error occurs
     67      * @see java.io.OutputStream#write(byte[], int, int)
     68      */
     69     public void write(byte[] b, int off, int len) throws IOException {
     70         count += len;
     71         super.write(b, off, len);
     72     }
     73 
     74     /**
     75      * Writes a single byte to the output stream adding to the count of the
     76      * number of bytes written.
     77      *
     78      * @param b  the byte to write
     79      * @throws IOException if an I/O error occurs
     80      * @see java.io.OutputStream#write(int)
     81      */
     82     public void write(int b) throws IOException {
     83         count++;
     84         super.write(b);
     85     }
     86 
     87     //-----------------------------------------------------------------------
     88     /**
     89      * The number of bytes that have passed through this stream.
     90      * <p>
     91      * NOTE: From v1.3 this method throws an ArithmeticException if the
     92      * count is greater than can be expressed by an <code>int</code>.
     93      * See {@link #getByteCount()} for a method using a <code>long</code>.
     94      *
     95      * @return the number of bytes accumulated
     96      * @throws ArithmeticException if the byte count is too large
     97      */
     98     public synchronized int getCount() {
     99         long result = getByteCount();
    100         if (result > Integer.MAX_VALUE) {
    101             throw new ArithmeticException("The byte count " + result + " is too large to be converted to an int");
    102         }
    103         return (int) result;
    104     }
    105 
    106     /**
    107      * Set the byte count back to 0.
    108      * <p>
    109      * NOTE: From v1.3 this method throws an ArithmeticException if the
    110      * count is greater than can be expressed by an <code>int</code>.
    111      * See {@link #resetByteCount()} for a method using a <code>long</code>.
    112      *
    113      * @return the count previous to resetting
    114      * @throws ArithmeticException if the byte count is too large
    115      */
    116     public synchronized int resetCount() {
    117         long result = resetByteCount();
    118         if (result > Integer.MAX_VALUE) {
    119             throw new ArithmeticException("The byte count " + result + " is too large to be converted to an int");
    120         }
    121         return (int) result;
    122     }
    123 
    124     /**
    125      * The number of bytes that have passed through this stream.
    126      * <p>
    127      * NOTE: This method is an alternative for <code>getCount()</code>.
    128      * It was added because that method returns an integer which will
    129      * result in incorrect count for files over 2GB.
    130      *
    131      * @return the number of bytes accumulated
    132      * @since Commons IO 1.3
    133      */
    134     public synchronized long getByteCount() {
    135         return this.count;
    136     }
    137 
    138     /**
    139      * Set the byte count back to 0.
    140      * <p>
    141      * NOTE: This method is an alternative for <code>resetCount()</code>.
    142      * It was added because that method returns an integer which will
    143      * result in incorrect count for files over 2GB.
    144      *
    145      * @return the count previous to resetting
    146      * @since Commons IO 1.3
    147      */
    148     public synchronized long resetByteCount() {
    149         long tmp = this.count;
    150         this.count = 0;
    151         return tmp;
    152     }
    153 
    154 }
    155