@Override public long length() throws IOException { ensureOpen(); return inspectable + writePosition; }
@Override public long position() throws IOException { ensureOpen(); return position; }
@Override public long skip(final long n) throws IOException { ensureOpen(); final long toSkip = Math.min(n, length() - position); position += toSkip; return toSkip; }
@Override public int read() throws IOException { ensureOpen(); if (position == length()) return -1; // Nothing to read if (position < inspectable) return buffer[(int)position++] & 0xFF; fileChannel.position(position - inspectable); position++; return randomAccessFile.read(); }
@Override public void reset() throws IOException { ensureOpen(); if (mark == -1) throw new IOException("Mark has not been set"); position(mark); }
@Override public int available() throws IOException { ensureOpen(); return (int)Math.min(Integer.MAX_VALUE, length() - position); }
/** Appends the content of a specified buffer to the end of the currently represented stream. * * @param byteBuffer a byte buffer. * @return the number of bytes appended (i.e., {@link ByteBuffer#remaining() byteBuffer.remaining()}). */ @Override public int write(final ByteBuffer byteBuffer) throws IOException { ensureOpen(); final int remaining = byteBuffer.remaining(); if (inspectable < buffer.length) { // Still some space in the inspectable buffer. final int toBuffer = Math.min(buffer.length - inspectable, remaining); byteBuffer.get(buffer, inspectable, toBuffer); inspectable += toBuffer; } if (byteBuffer.hasRemaining()) { fileChannel.position(writePosition); writePosition += fileChannel.write(byteBuffer); } return remaining; }
@Override public int read(final byte[] b, int offset, int length) throws IOException { ensureOpen(); if (length == 0) return 0; if (position == length()) return -1; // Nothing to read. ByteArrays.ensureOffsetLength(b, offset, length); int read = 0; if (position < inspectable) { /* The first min(inspectable - readPosition, length) bytes should be taken from the buffer. */ final int toCopy = Math.min(inspectable - (int)position, length); System.arraycopy(buffer, (int)position, b, offset, toCopy); length -= toCopy; offset += toCopy; position += toCopy; read = toCopy; } if (length > 0) { // We want to read more. if (position == length()) return read != 0 ? read : -1; // There's nothing more to read. fileChannel.position(position - inspectable); final int toRead = (int)Math.min(length() - position, length); // This is *intentionally* not a readFully(). Let the language to its stuff. final int t = randomAccessFile.read(b, offset, toRead); position += t; read += t; } return read; }