
com.gc.iotools.stream.writer.SizeLimitReader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of easystream Show documentation
Show all versions of easystream Show documentation
EasyStream is a small set of utilities for dealing with
streams (InputStreams
and OutputStreams).
The aim is to ease the use of
pipes when they're required.
Main features are:
* "Convert" an
OutputStream to an InputStream.
* Count the number of bytes read or
wrote to a given stream.
* While reading the data from an InputStream
copy it to a supplied
OutputStream.
* Read the content of an InputStream
multiple times or seek to a
definite position
The newest version!
package com.gc.iotools.stream.writer;
/*
* Copyright (c) 2008, 2015 Gabriele Contini. This source code is released
* under the BSD License.
*/
import java.io.IOException;
import java.io.Reader;
/**
* A Reader
wrapper that will read only a definite number of
* characters from the underlying stream.
*
* @author Gabriele Contini
* @since 1.2.15
*/
public class SizeLimitReader extends Reader {
private boolean closed = false;
/**
* The number of characters that have been read from the {@link #in} stream.
* Read methods should check to ensure that currentPosition never exceeds
* {@link #maxSize}.
*/
protected long currentPosition = 0;
/**
* The underlying stream from which data are read. All methods are forwarded
* to it, after checking that the {@linkplain #maxSize} size that hasn't
* been reached.
*/
protected Reader in;
/**
* The position in the stream when {@linkplain #mark} was called. It's used
* to reset the current position when {@linkplain #reset} is called.
*/
protected long markPosition = 0;
/**
* The number of characters to read at most from the {@link #in} stream.
* Read methods should check to ensure that the number of characters read
* never exceeds maxSize.
*/
protected final long maxSize;
/**
*
* Create a new SizeLimitInputStream
from another stream given
* a size limit.
*
*
* Bytes are read from the underlying stream until size limit is reached.
*
*
* @param in
* The underlying input stream from where the data is read.
* @param maxSize
* the max number of characters to allow to be read from the
* underlying stream.
*/
public SizeLimitReader(final Reader in, final long maxSize) {
this.in = in;
this.maxSize = maxSize;
}
/**
*
* Close the underlying stream. Calling this method may make data on the
* underlying stream unavailable.
*
* {@inheritDoc}
*/
@Override
public void close() throws IOException {
if (!this.closed) {
// some buggy inputStream doesn't support close() call twice.
this.closed = true;
this.in.close();
}
}
/**
* Get the maximum number of characters left to read before the limit, set
* in the constructor, is reached.
*
* @return The number of characters that (at a maximum) are left to be taken
* from this stream.
*/
public long getBytesLeft() {
return this.maxSize - this.currentPosition;
}
/**
* Get the number of characters actually read from this stream.
*
* @return number of characters that have already been taken from this
* stream.
*/
public long getBytesRead() {
return this.currentPosition;
}
/**
* Get the number of total characters (including characters already read)
* that can be read from this stream (as set in the constructor).
*
* @return Maximum characters that can be read until the size limit runs out
*/
public long getMaxSize() {
return this.maxSize;
}
/** {@inheritDoc} */
@Override
public void mark(final int readlimit) throws IOException {
this.in.mark(readlimit);
this.markPosition = this.currentPosition;
}
/** {@inheritDoc} */
@Override
public boolean markSupported() {
return this.in.markSupported();
}
/** {@inheritDoc} */
@Override
public int read() throws IOException {
int result;
if (this.currentPosition >= this.maxSize) {
result = -1;
} else {
result = this.in.read();
if (result >= 0) {
this.currentPosition++;
}
}
return result;
}
/** {@inheritDoc} */
@Override
public int read(final char[] b) throws IOException {
return this.read(b, 0, b.length);
}
/** {@inheritDoc} */
@Override
public int read(final char[] b, final int off, final int len)
throws IOException {
int charactersRead;
if (this.currentPosition >= this.maxSize) {
charactersRead = -1;
} else {
final int n = (int) Math.min(getBytesLeft(), len);
charactersRead = this.in.read(b, off, n);
if (charactersRead > 0) {
this.currentPosition += charactersRead;
}
}
return charactersRead;
}
/** {@inheritDoc} */
@Override
public void reset() throws IOException {
this.in.reset();
this.currentPosition = this.markPosition;
this.markPosition = 0;
}
/** {@inheritDoc} */
@Override
public long skip(final long n) throws IOException {
long result;
if (this.currentPosition >= this.maxSize) {
result = -1;
} else {
result = this.in.skip(Math.min(n, getBytesLeft()));
if (result > 0) {
this.currentPosition += result;
}
}
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy