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.commons.io.output;
018:
019: import java.io.IOException;
020: import java.io.OutputStream;
021:
022: /**
023: * A decorating output stream that counts the number of bytes that have passed
024: * through the stream so far.
025: * <p>
026: * A typical use case would be during debugging, to ensure that data is being
027: * written as expected.
028: *
029: * @version $Id: CountingOutputStream.java 471628 2006-11-06 04:06:45Z bayard $
030: */
031: public class CountingOutputStream extends ProxyOutputStream {
032:
033: /** The count of bytes that have passed. */
034: private long count;
035:
036: /**
037: * Constructs a new CountingOutputStream.
038: *
039: * @param out the OutputStream to write to
040: */
041: public CountingOutputStream(OutputStream out) {
042: super (out);
043: }
044:
045: //-----------------------------------------------------------------------
046: /**
047: * Writes the contents of the specified byte array to this output stream
048: * keeping count of the number of bytes written.
049: *
050: * @param b the bytes to write, not null
051: * @throws IOException if an I/O error occurs
052: * @see java.io.OutputStream#write(byte[])
053: */
054: public void write(byte[] b) throws IOException {
055: count += b.length;
056: super .write(b);
057: }
058:
059: /**
060: * Writes a portion of the specified byte array to this output stream
061: * keeping count of the number of bytes written.
062: *
063: * @param b the bytes to write, not null
064: * @param off the start offset in the buffer
065: * @param len the maximum number of bytes to write
066: * @throws IOException if an I/O error occurs
067: * @see java.io.OutputStream#write(byte[], int, int)
068: */
069: public void write(byte[] b, int off, int len) throws IOException {
070: count += len;
071: super .write(b, off, len);
072: }
073:
074: /**
075: * Writes a single byte to the output stream adding to the count of the
076: * number of bytes written.
077: *
078: * @param b the byte to write
079: * @throws IOException if an I/O error occurs
080: * @see java.io.OutputStream#write(int)
081: */
082: public void write(int b) throws IOException {
083: count++;
084: super .write(b);
085: }
086:
087: //-----------------------------------------------------------------------
088: /**
089: * The number of bytes that have passed through this stream.
090: * <p>
091: * NOTE: From v1.3 this method throws an ArithmeticException if the
092: * count is greater than can be expressed by an <code>int</code>.
093: * See {@link #getByteCount()} for a method using a <code>long</code>.
094: *
095: * @return the number of bytes accumulated
096: * @throws ArithmeticException if the byte count is too large
097: */
098: public synchronized int getCount() {
099: long result = getByteCount();
100: if (result > Integer.MAX_VALUE) {
101: throw new ArithmeticException("The byte count " + result
102: + " is too large to be converted to an int");
103: }
104: return (int) result;
105: }
106:
107: /**
108: * Set the byte count back to 0.
109: * <p>
110: * NOTE: From v1.3 this method throws an ArithmeticException if the
111: * count is greater than can be expressed by an <code>int</code>.
112: * See {@link #resetByteCount()} for a method using a <code>long</code>.
113: *
114: * @return the count previous to resetting
115: * @throws ArithmeticException if the byte count is too large
116: */
117: public synchronized int resetCount() {
118: long result = resetByteCount();
119: if (result > Integer.MAX_VALUE) {
120: throw new ArithmeticException("The byte count " + result
121: + " is too large to be converted to an int");
122: }
123: return (int) result;
124: }
125:
126: /**
127: * The number of bytes that have passed through this stream.
128: * <p>
129: * NOTE: This method is an alternative for <code>getCount()</code>.
130: * It was added because that method returns an integer which will
131: * result in incorrect count for files over 2GB.
132: *
133: * @return the number of bytes accumulated
134: * @since Commons IO 1.3
135: */
136: public synchronized long getByteCount() {
137: return this .count;
138: }
139:
140: /**
141: * Set the byte count back to 0.
142: * <p>
143: * NOTE: This method is an alternative for <code>resetCount()</code>.
144: * It was added because that method returns an integer which will
145: * result in incorrect count for files over 2GB.
146: *
147: * @return the count previous to resetting
148: * @since Commons IO 1.3
149: */
150: public synchronized long resetByteCount() {
151: long tmp = this .count;
152: this .count = 0;
153: return tmp;
154: }
155:
156: }
|