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();
}
}