/* XXL: The eXtensible and fleXible Library for data processing Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger Head of the Database Research Group Department of Mathematics and Computer Science University of Marburg Germany This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; If not, see <http://www.gnu.org/licenses/>. http://code.google.com/p/xxl/ */ package xxl.core.io; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import xxl.core.util.WrappingRuntimeException; /** * This class provides a mechanism to read data via an * InputStream from a RandomAccessFile. The stream starts * reading at the current position of the underlying file. * A close of the stream does not close the file, so it * is still open for subsequent processing. */ public class RandomAccessFileInputStream extends InputStream { /** * The internally used RandomAccessFile */ protected RandomAccessFile raf; /** * Position set by the mark-operation (initially 0). */ protected long markPos; /** * Constructs an InputStream that reads its data from a * RandomAccessFile. * @param raf The RandomAccessFile used for input. */ public RandomAccessFileInputStream(RandomAccessFile raf) { this.raf = raf; this.markPos = 0; } /** * Reads a byte from the RandomAccessFile. * @return the read byte. -1 means end of file. * @throws IOException */ public int read() throws IOException { return raf.read(); } /** * Determines the number of bytes which can be read without * blocking. Here, it is the number of bytes left after the * current position in the file. * * @return available bytes * @throws IOException */ public int available() throws IOException { long avail = raf.length()-raf.getFilePointer(); return avail>Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) avail; } /** * Writes a byte array into the RandomAccessFile. * @param b byte array * @param off position of the first byte in the array * that should be written. * @param len length in bytes that should be written. * @return number of bytes read. -1 means end of file. * @throws IOException */ public int read(byte[] b,int off,int len) throws IOException { return raf.read(b,off,len); } /** * This class supports the mark-operation. * @return true */ public boolean markSupported() { return true; } /** * Marks the position in the RandomAccessFile. * @param readlimit has no effekt in this class */ public void mark(int readlimit) { try { markPos = raf.getFilePointer(); } catch (IOException e) { throw new WrappingRuntimeException(e); } } /** * Resets the position inside the RandomAccessFile to a * position that has been marked before (or to the beginning * of the file if no position has been marked). * @throws IOException */ public void reset() throws IOException { raf.seek(markPos); } /** * Skips n bytes of the input stream (if possible). * @param n number of bytes to be skipped. * @return number of bytes which have really been skipped. * @throws IOException */ public long skip(long n) throws IOException { return raf.skipBytes((int) n); } /** * Disconnects the OutputStream. Further calls to the OutputStream * are not allowed. */ public void close() { raf = null; } }