java按行读取byte_【util】MappedByteBuffer按行读取的方案
原始代碼出處:http://blog.163.com/cazwxy_12/blog/static/8987637201611161426426/
最近有個寫日志的需求,已經有一個方案是通過randomaccessfile進行逐行讀取,但是偶爾會出現bug,雖然我可以通過try catch去捕獲寫進錯誤日志,不過這樣難免不夠好,希望有一個沒有bug的版本。。。我希望用MappedByteBuffer寫出按行讀取的方案,于是百度了一下,卻無意中找到一個用MappedByteBuffer寫的util,想法和我的一樣,先通過通道進行一部分buffer的壓入,然后處理篩出有效的內容。
代碼如下
package com.shijia.test;
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.security.AccessController;
import java.security.PrivilegedAction;
/**
* MappedByteBufferReadLineUtil
* @author fish
*
*/
public class MappedByteBufferReadLineUtil {
private FileInputStream fis;
private FileChannel fc;
private MappedByteBuffer mbb;
private int currentReadPos;
private int limit ;
public MappedByteBufferReadLineUtil(File file) throws Exception{
if(!file.exists() || !file.isFile()){
throw new Exception("指定文件不存在或者不是一個文件");
}
fis = new FileInputStream(file);
fc = fis.getChannel();
mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
limit = mbb.limit();
}
public MappedByteBufferReadLineUtil(String filePath) throws Exception{
this(new File(filePath));
}
/**
* 指定每行的容量,最大字節數
* 如果存在行超過指定最大字節,則會
* @param capacity
* @return
* @throws Exception
*/
public String readLine(int capacity) throws Exception{
try{
if(currentReadPos >= limit){
return null;
}
ByteBuffer bb = ByteBuffer.allocate(capacity==0?1024:capacity);
while(currentReadPos < limit){
byte b = mbb.get();
currentReadPos++;
if(System.getProperty("line.separator").equals("\r\n") && b==13){
mbb.get();
currentReadPos++;
break;
}else if(b==10 || b==13){
break;
}else{
bb.put(b);
}
}
return rightTrim(new String(bb.array(),"GBK"));
}catch(Exception e){
clean();
throw e;
}finally{
fc.close();
fis.close();
}
}
/**
* 默認1024字節
* @return
* @throws Exception
*/
public String readLine() throws Exception{
return readLine(0);
}
/**
* 清理ByteBuffer
* @param buffer
* @throws Exception
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public void clean() throws Exception {
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
try {
Method getCleanerMethod = mbb.getClass().getMethod("cleaner",new Class[0]);
getCleanerMethod.setAccessible(true);
sun.misc.Cleaner cleaner =(sun.misc.Cleaner)getCleanerMethod.invoke(mbb,new Object[0]);
cleaner.clean();
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
});
}
private String rightTrim(String s){
char[] cs = s.toCharArray();
int pos= 0;
for(int i=cs.length-1;i>=0;i--){
String tostr = String.valueOf(cs[i]);
if(tostr.trim().length()!=0){
pos = i;
break ;
}
}
return s.substring(0,pos+1);
}
public static void main(String[] args){
MappedByteBufferReadLineUtil mbbrlutil = null;
try{
mbbrlutil = new MappedByteBufferReadLineUtil("C:\\Users\\shijia\\Desktop\\log-2017-10-27");
String line = null;
while((line = mbbrlutil.readLine())!=null){
System.out.println(line);
}
}catch(Exception e){
e.printStackTrace();
}finally{
try {
mbbrlutil.clean();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
總結
以上是生活随笔為你收集整理的java按行读取byte_【util】MappedByteBuffer按行读取的方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中科院的java_java 中调用中科院
- 下一篇: java basic类似的地方_java