Copyright (c) 2005, 2006 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation
/******************************************************************************* * Copyright (c) 2005, 2006 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/
package org.eclipse.core.internal.registry; import java.io.*;
Provides buffered read from a java.io.RandomAccessFile.
/** * Provides buffered read from a java.io.RandomAccessFile. */
public class BufferedRandomInputStream extends InputStream { private RandomAccessFile inputFile; private String filePath; // Canonical path to the underlying file used for logging private int buffer_size; // Current size of the buffer private int buffer_pos; // Current read position in the buffer
The absolute position in the file where the buffered region starts.
/** * The absolute position in the file where the buffered region starts. */
private long buffer_start = 0;
The current value of the RAF's file pointer.
/** * The current value of the RAF's file pointer. */
private long file_pointer; private byte buffer[]; public BufferedRandomInputStream(File file) throws IOException { this(file, 2048); // default buffer size } public BufferedRandomInputStream(File file, int bufferSize) throws IOException { filePath = file.getCanonicalPath(); inputFile = new RandomAccessFile(file, "r"); //$NON-NLS-1$ buffer = new byte[bufferSize]; file_pointer = 0; resetBuffer(); } private void resetBuffer() { buffer_pos = 0; buffer_size = 0; buffer_start = 0; } private int fillBuffer() throws IOException { buffer_pos = 0; buffer_start = file_pointer; buffer_size = inputFile.read(buffer, 0, buffer.length); file_pointer += buffer_size; return buffer_size; } @Override public int read() throws IOException { if (buffer_pos >= buffer_size) { if (fillBuffer() <= 0) return -1; } return buffer[buffer_pos++] & 0xFF; } @Override public int read(byte b[], int off, int len) throws IOException { int available = buffer_size - buffer_pos; if (available < 0) return -1; //the buffer contains all the bytes we need, so copy over and return if (len <= available) { System.arraycopy(buffer, buffer_pos, b, off, len); buffer_pos += len; return len; } // Use portion remaining in the buffer System.arraycopy(buffer, buffer_pos, b, off, available); if (fillBuffer() <= 0) return available; //recursive call to read again until we have the bytes we need return available + read(b, off + available, len - available); } @Override public long skip(long n) throws IOException { if (n <= 0) return 0; int available = buffer_size - buffer_pos; if (n <= available) { buffer_pos += n; return n; } resetBuffer(); final int skipped = inputFile.skipBytes((int) (n - available)); file_pointer += skipped; return available + skipped; } @Override public int available() { return (buffer_size - buffer_pos); } @Override public void close() throws IOException { inputFile.close(); inputFile = null; buffer = null; } @Override public String toString() { return filePath; }
Supplies functionality of the RandomAccessFile.seek(long) in a buffer-friendly manner.
Params:
  • pos – offset
Throws:
/** * Supplies functionality of the {@link java.io.RandomAccessFile#seek(long)} in * a buffer-friendly manner. * * @param pos offset * @throws IOException */
public void seek(long pos) throws IOException { if (pos >= buffer_start && pos < buffer_start + buffer_size) { //seeking within the current buffer buffer_pos = (int) (pos - buffer_start); } else { //seeking outside the buffer - just discard the buffer inputFile.seek(pos); file_pointer = pos; resetBuffer(); } }
Supplies functionality of the RandomAccessFile.length().
Throws:
Returns:file length
/** * Supplies functionality of the {@link java.io.RandomAccessFile#length()}. * @return file length * @throws IOException */
public long length() throws IOException { return inputFile.length(); } }