1. 程式人生 > >JAVA快速統計大文字檔案行數

JAVA快速統計大文字檔案行數

統計某檔案的文字行數,常用的方法是通過BufferedReader類的readLine()方法遞迴遍歷檔案,從而間接地統計行數。然而對於大的文字檔案,尤其是一些生信的測序檔案,readLine()的方法顯然不能讓人滿意,所以,通過查閱了一些資料,找到了一些更為高效的方法。測試檔案選擇了一個4985014行的檔案,檔案大小為242MB。測試耗時以毫秒為單位。

原始的readLine方法:

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;

public class LineNumberReaderExample
{
    public static void main(String[] args)
    {
    	try{
    		File file =new File("c:\\test.txt");
    		if(file.exists()){
    		    FileReader fr = new FileReader(file);
    		    LineNumberReader lnr = new LineNumberReader(fr);
    		    int linenumber = 0;
    	            while (lnr.readLine() != null){
    	        	linenumber++;
    	            }
    	            System.out.println("Total number of lines : " + linenumber);
    	            lnr.close();
    		}else{
    			 System.out.println("File does not exists!");
    		}
    	}catch(IOException e){
    		e.printStackTrace();
    	}
    }
} 

測試結果:

Total number of lines : 4985014

total time is:585

改進的方法使用了LineNumberReader類。

使用LineNumberReader類使用預設的輸入緩衝區大小來建立新的行號讀取器。skip方法用於跳過n個數字字元,所以在這裡我們跳過 檔案長度大小的字元,跳到檔案的末尾。getLineNumber()方法返回最後一行的當前行號。具體的程式碼如下:

 public static void main(String[] args) {
    	try {
    		File file = new File("e://test.fa");
    		if(file.exists()){
    			long fileLength = file.length();
    			LineNumberReader lineNumberReader = new LineNumberReader(new FileReader(file));
    			lineNumberReader.skip(fileLength);
    	                int lines = lineNumberReader.getLineNumber();
    	                System.out.println("Total number of lines : " + lines);
	                lineNumberReader.close();
    		}else {
    			System.out.println("File does not exists!");
    		}
    	}catch(IOException e) {
    		e.printStackTrace();
    	}
    }

測試結果:

Total number of lines : 4985014

total time is:466

此外,JAVA8的出現也為我們提供了一些新的思路

public class CountOfLines {
  public static void main(String[] args) {
    // for total number of lines in the File with Files.lines
    try {
    	long startTime=System.currentTimeMillis();
        long lines = Files.lines(Paths.get(new File("e://test.fa").getPath())).count();
        System.out.println("Total number of lines : " + lines);
        long endTime=System.currentTimeMillis();
        System.out.println("Total time is:"+ (endTime-startTime) );
    } catch (IOException e) {
      System.out.println("No File Found");
    }
  }
}

雖然程式碼變得簡單了一些,但是測試結果顯示時間花費很大。

測試結果:

Total number of lines : 4985014

Total time is:544

總結:

這三種方法的測試顯示第二種的時間花費是最少的,但時間花費的減少幅度並沒有很大。所以,當面對更大的檔案時,依舊需要尋找更為高效的方法。在shell命令列模式使用wc -l是一種相對來說最高效的方法,但考慮到在Java中過多使用外部命令,在Java中如何更快速地統計大文字檔案行數的問題依舊沒有解決。

參考文獻:

http://www.technicalkeeda.com/java-tutorials/count-total-number-of-lines-of-file-using-java

http://blog.csdn.net/kirayuan/article/details/6321900