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.input; 18 19 import static org.apache.commons.io.IOUtils.EOF; 20 21 import java.io.IOException; 22 import java.io.InputStream; 23 24 /** 25 * A decorating input stream that counts the number of bytes that have passed 26 * through the stream so far. 27 * <p> 28 * A typical use case would be during debugging, to ensure that data is being 29 * read as expected. 30 * </p> 31 * @deprecated Use {@link BoundedInputStream} (unbounded by default). 32 */ 33 @Deprecated 34 public class CountingInputStream extends ProxyInputStream { 35 36 /** The count of bytes read. */ 37 private long count; 38 39 /** 40 * Constructs a new CountingInputStream. 41 * 42 * @param in the InputStream to delegate to 43 */ 44 public CountingInputStream(final InputStream in) { 45 super(in); 46 } 47 48 CountingInputStream(final InputStream in, final ProxyInputStream.AbstractBuilder<?, ?> builder) { 49 super(in, builder); 50 } 51 52 CountingInputStream(final ProxyInputStream.AbstractBuilder<?, ?> builder) throws IOException { 53 super(builder); 54 } 55 56 /** 57 * Adds the number of read bytes to the count. 58 * 59 * @param n number of bytes read, or -1 if no more bytes are available 60 * @throws IOException Not thrown here but subclasses may throw. 61 * @since 2.0 62 */ 63 @Override 64 protected synchronized void afterRead(final int n) throws IOException { 65 if (n != EOF) { 66 count += n; 67 } 68 super.afterRead(n); 69 } 70 71 /** 72 * Gets number of bytes that have passed through this stream. 73 * <p> 74 * NOTE: This method is an alternative for {@code getCount()} 75 * and was added because that method returns an integer which will 76 * result in incorrect count for files over 2GB. 77 * </p> 78 * 79 * @return the number of bytes accumulated 80 * @since 1.3 81 */ 82 public synchronized long getByteCount() { 83 return count; 84 } 85 86 /** 87 * Gets number of bytes that have passed through this stream. 88 * <p> 89 * This method throws an ArithmeticException if the 90 * count is greater than can be expressed by an {@code int}. 91 * See {@link #getByteCount()} for a method using a {@code long}. 92 * </p> 93 * 94 * @return the number of bytes accumulated 95 * @throws ArithmeticException if the byte count is too large 96 * @deprecated Use {@link #getByteCount()}. 97 */ 98 @Deprecated 99 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 }