Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* BigByteBuffer allows mmaping files larger than Integer.MAX_VALUE bytes.
*/
public class BigByteBuffer {
private static int OVERLAP = Integer.MAX_VALUE / 2;
private final List<ByteBuffer> buffers;
/**
* mmap the file and return a BigByteBuffer for it.
* @param file the file to mmap
* @throws java.io.IOException if there is an error reading the file
*/
public BigByteBuffer(File file) throws IOException {
this(new RandomAccessFile(file, "r"));
}
/**
* mmap the file and return a BigByteBuffer for it.
* @param file the file to mmap
* @throws java.io.IOException if there is an error reading the file
*/
public BigByteBuffer(RandomAccessFile file) throws IOException {
long length = file.length();
if (length == 0) {
throw new IllegalArgumentException("File is empty");
}
buffers = new ArrayList<ByteBuffer>();
for (long i = 0; i < length; i += OVERLAP) {
buffers.add(file.getChannel().map(FileChannel.MapMode.READ_ONLY, i, Math.min(length - i, Integer.MAX_VALUE)));
}
}
/**
* Wrap a ByteBuffer. Used for testing.
* @param buffer the buffer to wrap
*/
public BigByteBuffer(ByteBuffer buffer) {
buffers = Arrays.asList(buffer);
}
/**
* Return a ByteBuffer starting at the specified location in the file
* @param position the starting position in the file
* @return ByteBuffer starting at the location in the file
*/
public ByteBuffer get(long position) {
ByteBuffer buffer = buffers.get((int) (position / OVERLAP));
buffer = buffer.duplicate();
buffer.position((int) (position % OVERLAP));
return buffer;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.