public class MappedFileRead
{
static final long G = 1024*1024*1024;
private static Logger log = Logger.getLogger(MappedFileRead.class);
public static void main(String[] args)
{
long start = - System.currentTimeMillis();
final File file = new File("E:\\test\\test.dat");
long length = file.length();
int defaultThreadNum = 4;//Runtime.getRuntime().availableProcessors();
long size = (length + defaultThreadNum - 1)/defaultThreadNum;
if (size > G)
{
defaultThreadNum = (int) ((length + G -1)/ G) ;
size = length/defaultThreadNum;
}
final CountDownLatch cdl = new CountDownLatch(defaultThreadNum);
long offset = 0;
long remain = length - offset;
for (int threadNum = 0;threadNum < defaultThreadNum;threadNum++)
{
if (size > remain)
{
size = remain;
}
try
{
final long offsetF = offset;
final long sizeF = size;
new Thread(new Runnable()
{
@Override
public void run()
{
MappedByteBuffer mappedByteBuffer = null;
try
{
System.out.println("freeMemory = " + Runtime.getRuntime().freeMemory() + " offsetF=" + offsetF + " sizeF=" + sizeF);
mappedByteBuffer = getMappedByteBuffer(file, MapMode.READ_ONLY, offsetF, sizeF);
while (null == mappedByteBuffer)
{
try
{
Thread.sleep(1000);
mappedByteBuffer = getMappedByteBuffer(file, MapMode.READ_ONLY, offsetF, sizeF);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
//e.printStackTrace();
}
}
System.out.println("mappedByteBuffer =" + mappedByteBuffer);
boolean isChangeLineAtLast = atLastIsChangeLine(mappedByteBuffer);
//Charset charset = Charset.defaultCharset();
//CharBuffer charBuffer = charset.decode(mappedByteBuffer);
String content = byteBufferToString(mappedByteBuffer);
System.out.println(content == null);
LineNumberReader read = new LineNumberReader(new StringReader(content));
String line = read.readLine();
while (null != line)
{
System.out.println(line);
line = read.readLine();
}
System.out.println(Thread.currentThread().getName() + "is end!");
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if (null != cdl)
{
cdl.countDown();
}
unmap(mappedByteBuffer);
}
}
}).start();
offset += size;
}
catch (Exception e)
{
cdl.countDown();
e.printStackTrace();
}
}
try
{
cdl.await();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
//计时= 376468
System.out.println( "计时= " + (System.currentTimeMillis() + start));
}
public static String byteBufferToString(ByteBuffer buffer)
{
CharBuffer charBuffer = null;
try
{
Charset charset = Charset.defaultCharset();
CharsetDecoder decoder = charset.newDecoder();
charBuffer = decoder.decode(buffer);
buffer.flip();
return charBuffer.toString();
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
}
/***
* 该映射区 最后一个字节 是否是换行符
* @param mappedByteBuffer
* @return
*/
public static boolean atLastIsChangeLine(MappedByteBuffer mappedByteBuffer)
{
if (null == mappedByteBuffer)
{
return false;
}
int bufferLength = mappedByteBuffer.limit();
byte indexByte = mappedByteBuffer.get(bufferLength - 1);
if ('\n' == indexByte)
{
return true;
}
return false;
}
/***
* 向映射文件写入字节
* @param mappedByteBuffer
* @param data
* @return
* @throws Exception
*/
public static boolean appendData(MappedByteBuffer mappedByteBuffer,byte[] data) throws Exception
{
if(null == mappedByteBuffer){
throw new Exception("mappedByteBuffer is null !");
}
mappedByteBuffer.put(data);
flush(mappedByteBuffer);
return true;
}
/**
* 强制写入到文件
* @param mappedByteBuffer
*/
private static void flush(MappedByteBuffer mappedByteBuffer)
{
if(null == mappedByteBuffer)
{
return;
}
mappedByteBuffer.force();
}
/***
* 映射文件
* @param file 文件
* @param fileMappedMode 映射模式
* @param offset 起始位置
* @param size 映射缓存大小
* @return
*/
public static MappedByteBuffer getMappedByteBuffer(File file,MapMode fileMappedMode,long offset,long size)
{
if (null == file)
{
log.error("file is null! ");
return null;
}
if (size > G)
{
log.error("Mapped File length is to Big! ");
return null;
}
if (offset < 0)
{
log.error("offset is less then 0");
return null;
}
if (null == fileMappedMode)
{
log.error(" fileMappedMode couldn't be null !");
return null;
}
String randomMode = "r";
if (fileMappedMode == MapMode.READ_WRITE|| fileMappedMode == MapMode.PRIVATE)
{
randomMode = "rw";
}
try
{
MappedByteBuffer map = new RandomAccessFile(file,randomMode).
getChannel().map(fileMappedMode, offset, size);
return map;
}
catch (Exception e)
{
// e.printStackTrace();
log.error("getMappedByteBuffer catch Exception = [" + e.getMessage() + "]",e);
}
return null;
}
public static void unmap(final MappedByteBuffer mappedByteBuffer) {
if (mappedByteBuffer == null)
{
return;
}
AccessController.doPrivileged(new PrivilegedAction<Object>()
{
public Object run() {
try {
Method getCleanerMethod = mappedByteBuffer.getClass().getMethod("cleaner", new Class[0]);
if (getCleanerMethod != null) {
getCleanerMethod.setAccessible(true);
Object cleaner = getCleanerMethod.invoke(mappedByteBuffer, new Object[0]);
Method cleanMethod = cleaner.getClass().getMethod("clean", new Class[0]);
if (cleanMethod != null) {
cleanMethod.invoke(cleaner, new Object[0]);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
});
}
}
<pre name="code" class="java">import java.util.StringTokenizer;
public class StringReaderUtils
{
private StringTokenizer stringTokenizer;
/**
* 创建一个根据分隔符 截去字符串工具
* @param content 字符串内容
* @param token 分隔符 比如换行符 或者其他标记
* @param isReturnToken 是否返回分隔符
*/
public StringReaderUtils(String content,String token,boolean isReturnToken)
{
stringTokenizer = new StringTokenizer(content,token,isReturnToken);
}
public static void main(String[] args)
{
}
/***
* 读取一截 字符
* @return
*/
public String readSection()
{
if (stringTokenizer.hasMoreTokens() && stringTokenizer.countTokens() > 0)
{
return stringTokenizer.nextToken();
}
return null;
}
/***
* 读取一截 字符
* @param token 新分隔符
* @return
*/
public String readSectionByNewToken(String token)
{
if (stringTokenizer.hasMoreTokens() && stringTokenizer.countTokens() > 0)
{
return stringTokenizer.nextToken(token);
}
return null;
}
/**
* 是否还有截去字符
* @return
*/
public boolean hasMoreSection()
{
return stringTokenizer.hasMoreTokens();
}
}