Skip to content

Instantly share code, notes, and snippets.

@wadey
Created May 9, 2014 18:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wadey/d61137a5553d7a2252c6 to your computer and use it in GitHub Desktop.
Save wadey/d61137a5553d7a2252c6 to your computer and use it in GitHub Desktop.
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