2017-01-10 103 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 ; 

} 
相关问题