AwdbBufferHolder.java
package com.xenoamess.ipplus360;
import com.xenoamess.ipplus360.enumerate.FileOpenMode;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
/**
* 构造一个缓冲器实例
*/
class AwdbBufferHolder {
private final ByteBuffer byteBuffer;
private final LargeFileBuffer largeFileBuffer;
private final RandomAccessFile randomAccessFile;
private final FileChannel fileChannel;
private final long fileSize;
private final boolean useLargeFile;
public AwdbBufferHolder(File file, FileOpenMode mode) throws IOException {
this.randomAccessFile = new RandomAccessFile(file, "r");
this.fileChannel = randomAccessFile.getChannel();
this.fileSize = fileChannel.size();
if (fileSize > Integer.MAX_VALUE) {
this.useLargeFile = true;
this.largeFileBuffer = new LargeFileBuffer(fileChannel, fileSize);
this.byteBuffer = null;
} else {
this.useLargeFile = false;
this.largeFileBuffer = null;
if (mode == FileOpenMode.MEMORY) {
this.byteBuffer = ByteBuffer.wrap(new byte[(int) fileSize]);
if (fileChannel.read(this.byteBuffer) != this.byteBuffer.capacity()) {
throw new IOException("Unable to read " + file.getName() + " into memory. Unexpected end of stream.");
}
this.byteBuffer.position(0);
} else {
this.byteBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileSize);
}
}
}
/**
* 返回是否使用大文件模式
*/
public boolean isLargeFile() {
return useLargeFile;
}
/**
* 返回 ByteBuffer 的独立副本(小文件模式),调用方各自维护 position/limit
*/
public ByteBuffer getByteBuffer() {
if (useLargeFile) {
throw new UnsupportedOperationException("Large file mode, use getLargeFileBuffer() instead");
}
return byteBuffer.duplicate();
}
/**
* 返回 LargeFileBuffer 的独立副本(大文件模式),避免多线程竞争
*/
public LargeFileBuffer getLargeFileBuffer() {
if (!useLargeFile) {
throw new UnsupportedOperationException("Small file mode, use getByteBuffer() instead");
}
return largeFileBuffer.duplicate();
}
public void close() throws IOException {
if (randomAccessFile != null) {
randomAccessFile.close();
}
}
}