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