001/* 002 * Copyright (C) 2007 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 005 * in compliance with the License. You may obtain a copy of the License at 006 * 007 * http://www.apache.org/licenses/LICENSE-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, software distributed under the License 010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 011 * or implied. See the License for the specific language governing permissions and limitations under 012 * the License. 013 */ 014 015package com.google.common.io; 016 017import static com.google.common.base.Preconditions.checkNotNull; 018 019import com.google.common.annotations.Beta; 020import com.google.common.annotations.GwtIncompatible; 021import java.io.FilterInputStream; 022import java.io.IOException; 023import java.io.InputStream; 024 025/** 026 * An {@link InputStream} that counts the number of bytes read. 027 * 028 * @author Chris Nokleberg 029 * @since 1.0 030 */ 031@Beta 032@GwtIncompatible 033public final class CountingInputStream extends FilterInputStream { 034 035 private long count; 036 private long mark = -1; 037 038 /** 039 * Wraps another input stream, counting the number of bytes read. 040 * 041 * @param in the input stream to be wrapped 042 */ 043 public CountingInputStream(InputStream in) { 044 super(checkNotNull(in)); 045 } 046 047 /** Returns the number of bytes read. */ 048 public long getCount() { 049 return count; 050 } 051 052 @Override 053 public int read() throws IOException { 054 int result = in.read(); 055 if (result != -1) { 056 count++; 057 } 058 return result; 059 } 060 061 @Override 062 public int read(byte[] b, int off, int len) throws IOException { 063 int result = in.read(b, off, len); 064 if (result != -1) { 065 count += result; 066 } 067 return result; 068 } 069 070 @Override 071 public long skip(long n) throws IOException { 072 long result = in.skip(n); 073 count += result; 074 return result; 075 } 076 077 @Override 078 public synchronized void mark(int readlimit) { 079 in.mark(readlimit); 080 mark = count; 081 // it's okay to mark even if mark isn't supported, as reset won't work 082 } 083 084 @Override 085 public synchronized void reset() throws IOException { 086 if (!in.markSupported()) { 087 throw new IOException("Mark not supported"); 088 } 089 if (mark == -1) { 090 throw new IOException("Mark not set"); 091 } 092 093 in.reset(); 094 count = mark; 095 } 096}