2017-01-10 80 views
0

我正在練習,並且遇到了一個有關從大到適合內存的文件中排序數字的問題。我不知道該怎麼做,所以我想我會試試看。我最終找到了外部排序,而我基本上只是試圖理解這個問題並編寫解決方案。我正在練習的文本文件不太適合內存;我只是想學習如何完成這樣的事情。 到目前爲止我正在從文件中讀取每個500行的3個塊,對塊進行排序,然後將結果塊寫入其自己的文件。這是工作...雖然我不知道我的實現是外部排序過程是如何打算實現:如何讀取要存儲在內存中的大塊文件

import java.util.*; 
import java.io.*; 

public class ExternalSort{ 

public static void main(String[] args) { 
    File file = new File("Practice/lots_of_numbers.txt"); 
    final int NUMBER_OF_CHUNKS = 3; 
    final int AMOUNT_PER_CHUNK = 500; 
    int numbers[][] = new int[NUMBER_OF_CHUNKS][AMOUNT_PER_CHUNK]; 

    try{ 
    Scanner scanner = new Scanner(file); 

    for(int i = 0; i < NUMBER_OF_CHUNKS; i++){ 
     //Just creating a new file name for each chunk 
     StringBuilder sortedFileName = new StringBuilder().append("sortedFile").append(i).append(".txt"); 

     for(int j = 0; j < AMOUNT_PER_CHUNK; j++){ 
     numbers[i][j] = Integer.parseInt(scanner.nextLine()); 
     } 
     Arrays.sort(numbers[i]); 
     saveResultsToFile(sortedFileName.toString(),numbers[i]); 
    } 

     scanner.close(); 
    }catch(FileNotFoundException e){ 
    System.out.println("Error: " + e); 
    } 
    } 

public static void saveResultsToFile(String fileName, int arr[]){ 
    try{ 
    File file = new File(fileName); 
    PrintWriter printer = new PrintWriter(file); 

    for(int i : arr) 
     printer.println(i); 

    printer.close(); 
    }catch(FileNotFoundException e){ 
    System.out.println("Error :" + e); 
    } 

} 

} 

我的問題是我怎麼分手文件到塊?我碰巧知道我的文件有多少行文本,因爲我創建了它,所以很容易編寫此代碼......但問題實際上告訴你文件的大小;如在內存中,不是多少行的文本文件。我不確定如何將數據分解爲「內存塊」(以及如何調整它們的大小)而不是文本行。另外,如果我的代碼,錯誤或不好的練習有什麼奇怪的話,請告訴我,因爲我真的不知道自己在做什麼;我只是想學習。至於將排序後的文件合併到一起,我也不知道該怎麼做,但我有一個想法。在我尋求幫助之前,我想嘗試一下。謝謝!

+0

我建議你使用'BufferedReader'代替掃描儀打開,特別是如果它的文件大。 –

+0

感謝您的建議。有理由嗎?我不熟悉BufferedReader類 –

+0

使用'BufferedReader',您可以在緩衝區中讀取文件的一小部分(字符數可以更改或保留爲默認大小),這樣您就不必擔心關於走出內存。 –

回答

0

這是怎麼得到我們想要打破文件到塊的大小:

public static long chunkSize(File file){ 
    //We don't want to create more that 1024 temp files for sorting 
    final long MAX_AMOUNT_OF_TEMP_FILES = 1024; 
    long fileSize = file.length(); 
    long freeMemory = Runtime.getRuntime().freeMemory(); 

    //We want to divide the file size by the maximum amount of temp files we will use for sorting 
    long chunkSize = fileSize/MAX_AMOUNT_OF_TEMP_FILES; 

    //If the block size is less than half the available memory, then we can stand to make the block size larger 
    if(chunkSize < freeMemory/2) 
    chunkSize = freeMemory/2; 
    else 
    System.out.println("Me may potentially run out of memory"); 

    return chunkSize ; 

} 
相關問題