標籤:except system dev htm close target test dex 參考
我們知道記憶體對應檔讀取是各種讀取方式中速度最快的,但是記憶體對應檔讀取的API裡沒有提供按行讀取的方法,需要自己實現。下面就是我利用記憶體對應檔實現按行讀取檔案的方法,如有錯誤之處請指出,或者有更好更快的實現方式麻煩也提供一下代碼。
代碼如下:
public class testMemoryMappedFile {public static void main(String[] agrs) throws IOException{RandomAccessFile memoryMappedFile = new RandomAccessFile("D://test.txt","r");int size =(int)memoryMappedFile.length();MappedByteBuffer out = memoryMappedFile.getChannel().map(FileChannel.MapMode.READ_ONLY,0,size);long start = System.currentTimeMillis();//要根據檔案行的平均位元組大小來賦值final int extra = 200;int count = extra;byte[] buf = new byte[count];int j=0;char ch =‘\0‘;boolean flag = false;while(out.remaining()>0){byte by = out.get();ch =(char)by;switch(ch){case ‘\n‘:flag = true;break;case ‘\r‘:flag = true;break;default:buf[j] = by;break;}j++;//讀取的字元超過了buf 數組的大小,需要動態擴容if(flag ==false && j>=count){count = count + extra;buf = copyOf(buf,count);}if(flag==true){//這裡的編碼要看檔案實際的編碼String line = new String(buf,"utf-8");System.out.println(line);flag = false;buf = null;count = extra;buf = new byte[count];j =0;}}//處理最後一次讀取if(j>0){String line = new String(buf,"utf-8");System.out.println(line);}long end = System.currentTimeMillis();System.out.println("耗時:"+(end-start)); memoryMappedFile.close();}//擴充數組的容量public static byte[] copyOf(byte[] original,int newLength){byte[] copy = new byte[newLength];System.arraycopy(original,0,copy,0,Math.min(original.length,newLength));return copy;}}
經過測試,可以達到50M/s的速度,依然比RandomAccessFile按行讀取快100倍以上。
注意點:byte[] buf 這個位元組數組的大小要動態擴容,如果一直固定的話速度也會比較慢,特別是如果設定很大的話,會更加慢。
參考部落格:https://www.ibm.com/developerworks/cn/java/l-javaio/index.html 這個部落格值得一看,對各個讀取方式的速度做了一個比較,同時自己實現了最佳化的方法
Java利用記憶體對應檔實現按行讀取檔案