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 */ 017package org.apache.commons.io.input; 018 019import static org.apache.commons.io.IOUtils.EOF; 020 021import java.io.IOException; 022import java.io.InputStream; 023 024/** 025 * A decorating input stream that counts the number of bytes that have passed 026 * through the stream so far. 027 * <p> 028 * A typical use case would be during debugging, to ensure that data is being 029 * read as expected. 030 * </p> 031 * @deprecated Use {@link BoundedInputStream} (unbounded by default). 032 */ 033@Deprecated 034public class CountingInputStream extends ProxyInputStream { 035 036 /** The count of bytes read. */ 037 private long count; 038 039 /** 040 * Constructs a new CountingInputStream. 041 * 042 * @param in the InputStream to delegate to 043 */ 044 public CountingInputStream(final InputStream in) { 045 super(in); 046 } 047 048 CountingInputStream(final InputStream in, final ProxyInputStream.AbstractBuilder<?, ?> builder) { 049 super(in, builder); 050 } 051 052 CountingInputStream(final ProxyInputStream.AbstractBuilder<?, ?> builder) throws IOException { 053 super(builder); 054 } 055 056 /** 057 * Adds the number of read bytes to the count. 058 * 059 * @param n number of bytes read, or -1 if no more bytes are available 060 * @throws IOException Not thrown here but subclasses may throw. 061 * @since 2.0 062 */ 063 @Override 064 protected synchronized void afterRead(final int n) throws IOException { 065 if (n != EOF) { 066 count += n; 067 } 068 super.afterRead(n); 069 } 070 071 /** 072 * Gets number of bytes that have passed through this stream. 073 * <p> 074 * NOTE: This method is an alternative for {@code getCount()} 075 * and was added because that method returns an integer which will 076 * result in incorrect count for files over 2GB. 077 * </p> 078 * 079 * @return the number of bytes accumulated 080 * @since 1.3 081 */ 082 public synchronized long getByteCount() { 083 return count; 084 } 085 086 /** 087 * Gets number of bytes that have passed through this stream. 088 * <p> 089 * This method throws an ArithmeticException if the 090 * count is greater than can be expressed by an {@code int}. 091 * See {@link #getByteCount()} for a method using a {@code long}. 092 * </p> 093 * 094 * @return the number of bytes accumulated 095 * @throws ArithmeticException if the byte count is too large 096 * @deprecated Use {@link #getByteCount()}. 097 */ 098 @Deprecated 099 public int getCount() { 100 final long result = getByteCount(); 101 if (result > Integer.MAX_VALUE) { 102 throw new ArithmeticException("The byte count " + result + " is too large to be converted to an int"); 103 } 104 return (int) result; 105 } 106 107 /** 108 * Resets the byte count back to 0. 109 * <p> 110 * NOTE: This method is an alternative for {@code resetCount()} 111 * and was added because that method returns an integer which will 112 * result in incorrect count for files over 2GB. 113 * </p> 114 * 115 * @return the count previous to resetting 116 * @since 1.3 117 */ 118 public synchronized long resetByteCount() { 119 final long tmp = count; 120 count = 0; 121 return tmp; 122 } 123 124 /** 125 * Resets the byte count back to 0. 126 * <p> 127 * This method throws an ArithmeticException if the 128 * count is greater than can be expressed by an {@code int}. 129 * See {@link #resetByteCount()} for a method using a {@code long}. 130 * </p> 131 * 132 * @return the count previous to resetting 133 * @throws ArithmeticException if the byte count is too large 134 * @deprecated Use {@link #resetByteCount()}. 135 */ 136 @Deprecated 137 public int resetCount() { 138 final long result = resetByteCount(); 139 if (result > Integer.MAX_VALUE) { 140 throw new ArithmeticException("The byte count " + result + " is too large to be converted to an int"); 141 } 142 return (int) result; 143 } 144 145 /** 146 * Skips the stream over the specified number of bytes, adding the skipped 147 * amount to the count. 148 * 149 * @param length the number of bytes to skip 150 * @return the actual number of bytes skipped 151 * @throws IOException if an I/O error occurs. 152 * @see java.io.InputStream#skip(long) 153 */ 154 @Override 155 public synchronized long skip(final long length) throws IOException { 156 final long skip = super.skip(length); 157 count += skip; 158 return skip; 159 } 160 161}