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 + " 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 }