All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fqlite.util.RandomAccessFileReader Maven / Gradle / Ivy

package fqlite.util;

import java.io.IOException;
import java.nio.Buffer;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;

public class RandomAccessFileReader extends LongPositionByteBuffer {

    private static final int BUFFER_SIZE = 65536;

    private FileChannel channel;
    private ByteBuffer buffer;
    private long position;
    private long size;
    private long bufferPosition;
    

    public RandomAccessFileReader(Path path) throws IOException {
        super();
        channel = FileChannel.open(path, StandardOpenOption.READ);
        size = channel.size();
        position = 0;
        bufferPosition = -1;
        buffer = ByteBuffer.allocate(BUFFER_SIZE);
        fillBuffer();
    }

    public long position() {
        return position;
    }

    public long position(long newPosition) throws IOException {
        if (newPosition > size) {
            throw new BufferUnderflowException();
        }
        synchronized (lock) {
            long oldPosition = position;
            position = newPosition;
            fillBuffer();
            return oldPosition;
        }
    }

    public byte get() throws IOException {
        synchronized (lock) {
            if (position > size) {
                throw new BufferUnderflowException();
            }
            if (buffer.remaining() == 0) {
                fillBuffer();
            }
            byte resp = buffer.get();
            position(position + 1);
            return resp;
        }
    }

    public LongPositionByteBuffer get(byte[] dst, int offset, int length) throws IOException {
        synchronized (lock) {
            position(position);
            while (length > 0) {
                int toRead = Math.min(length, buffer.remaining());
                if (toRead == 0) {
                    throw new BufferUnderflowException();
                }
                buffer.get(dst, offset, toRead);
                position(position + toRead);
                offset += toRead;
                length -= toRead;
            }
            return this;
        }
    }

    public LongPositionByteBuffer get(byte[] dst) throws IOException {
        synchronized (lock) {
            return get(dst, 0, dst.length);
        }
    }

    private void fillBuffer() throws IOException {
        long newBufferPos = position / BUFFER_SIZE;
        int positionInBuffer = (int) (position % BUFFER_SIZE);
        if (newBufferPos != bufferPosition) {
            bufferPosition = newBufferPos;
            ((Buffer) buffer).clear();
            channel.position(bufferPosition * BUFFER_SIZE);
            channel.read(buffer);
            buffer.flip();
        }
        buffer.position(positionInBuffer);
    }

    public long size() {
        return size;
    }

    @Override
    public void close() throws IOException {
        synchronized (lock) {
            channel.close();
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy