博客年龄:17年6个月
访问:?
文章:291篇

个人描述

姓名:丹臣 职业:DBA 公司:TAOBAO Mail:zhaolinjnu(at)163.com MSN:echo_lin@hotmail.com 微博http://twitter.com/zhaolinjnu

MappedByteBuffer的学习

分类:Java | 标签: MappedByteBuffer   file   zhaolinjnu  
2013-05-29 17:31 阅读(?)评论(0)
MappedByteBuffer是什么?
A direct byte buffer whose content is a memory-mapped region of a file.更多详细的解释参考Oracle的官方文档:
http://docs.oracle.com/javase/6/docs/api/java/nio/MappedByteBuffer.html

我了解这个对象,是因为公司内有同事利用这项技术,加以合理的架构设计,使得我们的XX系统,有很大的性能提升,并且解决了以前遇到的一些问题。

我写了一个简单的测试代码:

package com.taobao.danchen.bytebuffer;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

public class MappedFile {
//文件名
private String fileName;
//文件路径
private String filePath;
//文件对象
private File file;
private MappedByteBuffer mappedByteBuffer;
private FileChannel fileChannel;
private boolean bundSuccess=false;
//文件大小
private final static long MAX_FILE_SIZE = 1024*1024*50;
//文件写入位置
private long writePosition = 0;
//最后一次刷数据的时间
private long lastFlushTime;
//上一次刷的文件位置
private long lastFlushFilePosition=0;
//最大的脏数据量,系统必须触发一次强制刷
private long MAX_FLUSH_DATA_SIZE = 1024*512;
//最大的时间间隔,系统必须触发一次强制刷
private long MAX_FLUSH_TIME_GAP = 1000;

public MappedFile(String fileName, String filePath) {
super();
this.fileName = fileName;
this.filePath = filePath;
this.file = new File(filePath+"/"+fileName);
if(!file.exists()){
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
 * 内存映射文件绑定
 * @return
 */
public synchronized boolean boundChannelToByteBuffer(){
try {
RandomAccessFile raf = new RandomAccessFile(file, "rw");
this.fileChannel = raf.getChannel();
} catch (Exception e) {
e.printStackTrace();
this.bundSuccess=false;
return false;
}
try {
this.mappedByteBuffer = this.fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, MAX_FILE_SIZE);
} catch (IOException e) {
e.printStackTrace();
this.bundSuccess=false;
return false;
}
this.bundSuccess=true;
return true;
}
public synchronized boolean appendData(byte[] data) throws Exception{
if(!bundSuccess){
throw new Exception("内存映射文件没有建立,请检查...");
}
writePosition = writePosition + data.length;
if(writePosition >= MAX_FILE_SIZE){
flush();
writePosition = writePosition - data.length;
System.out.println("File="+file.toURI().toString()+" is writed full.");
System.out.println("already write data length:"+writePosition+"max file size="+MAX_FILE_SIZE);
return false;
}
this.mappedByteBuffer.put(data);
//检测修改量
if(writePosition-lastFlushFilePosition>this.MAX_FLUSH_DATA_SIZE){
flush();
}
//检测时间间隔
if(System.currentTimeMillis()-lastFlushTime>this.MAX_FLUSH_TIME_GAP && writePosition>lastFlushFilePosition){
flush();
}
return true;
}
 
public synchronized void flush(){
this.mappedByteBuffer.force();
this.lastFlushTime=System.currentTimeMillis();
this.lastFlushFilePosition=writePosition;
}


public long getLastFlushTime() {
return lastFlushTime;
}


public String getFileName() {
return fileName;
}


public String getFilePath() {
return filePath;
}


public boolean isBundSuccess() {
return bundSuccess;
}


public File getFile() {
return file;
}


public static long getMaxFileSize() {
return MAX_FILE_SIZE;
}


public long getWritePosition() {
return writePosition;
}


public long getLastFlushFilePosition() {
return lastFlushFilePosition;
}


public long getMAX_FLUSH_DATA_SIZE() {
return MAX_FLUSH_DATA_SIZE;
}


public long getMAX_FLUSH_TIME_GAP() {
return MAX_FLUSH_TIME_GAP;
}
}

我在想,很多基础的技术与知识其实已经存在了很多年,如何把这项技术与具体的哪一种场景相结合,是一种能力。我在本篇文章中,出于信息安全的考虑,并不会透露具体的场景,以及相关的设计,用法。只是告诉大家,这个东东在一些场景下将发挥巨大的作用。

如果没有用过这个的,可以练习一下。
 
表  情:
加载中...
 

请各位遵纪守法并注意语言文明