原理:内存映射文件原理探索
java对象解析:java内存映射文件
java对象中,介绍是用普通的bytebuffer来做的,而我们在实际生产环境中使用MappedByteBuffer。
介绍中是操作FileChannel的write、force、close等方法。使用MappedByteBuffer = FileChannel.map(..)产生,只要操作MappedByteBuffer的put、force方法就好了
MappedByteBuffer代码:
package file.ram.map;
import sun.misc.Cleaner;
import sun.nio.ch.DirectBuffer;
import sun.nio.ch.FileChannelImpl;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.atomic.AtomicInteger;
public class FileMMap {
private static AtomicInteger pos = new AtomicInteger();
private static FileChannel channel;
private static MappedByteBuffer mmap;
private static long size = 1024L;
public static void main(String[] args) throws IOException, InterruptedException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
File file = new File("./test.dump");
channel = FileChannel.open(file.toPath(), StandardOpenOption.CREATE,
StandardOpenOption.READ, StandardOpenOption.WRITE);
mmap = channel.map(FileChannel.MapMode.READ_WRITE, 0, size);
byte[] len = new byte[8];
mmap.get(len);
System.out.println(mmap.capacity());
System.out.println(mmap.limit());
System.out.println(mmap.remaining());
mmap.put("abc".getBytes(StandardCharsets.UTF_8));
// channel.close();
// System.out.println(mmap.slice());
for (int i = 0; i < 10000; i++) {
// channel.transferTo(0, channel.size(), FileChannel.open(new File("./test1.dump").toPath(),
// StandardOpenOption.CREATE, StandardOpenOption.WRITE));
// 移动
Files.move(file.toPath(), new File("./test1.dump").toPath(),
StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
channel.close();
// 新建
channel = FileChannel.open(file.toPath(), StandardOpenOption.CREATE,
StandardOpenOption.READ, StandardOpenOption.WRITE);
// 手动unmap
// Method m = FileChannelImpl.class.getDeclaredMethod("unmap",
// MappedByteBuffer.class);
// m.setAccessible(true);
// m.invoke(FileChannelImpl.class, mmap);
// 可以直接释放MappedByteBuffer
Cleaner var1 = ((DirectBuffer)mmap).cleaner();
if(var1 != null) {
var1.clean();
}
mmap = channel.map(FileChannel.MapMode.READ_WRITE, 0, size);
mmap.put(String.valueOf(i + 1).getBytes(StandardCharsets.UTF_8));
}
}
}