0

我正在练习,我遇到了一个关于从一个太大而无法放入内存的文件中排序数字的问题。我不知道如何做到这一点,所以我想我会试一试。我最终找到了外部排序,我基本上只是试图采用这个概念并编写一个解决这个问题的代码。我正在练习的文本文件没有那么大,无法放入内存。我只是想学习如何完成这样的事情。到目前为止,我正在从文件中读取 3 个块,每块 500 行,对块进行排序,然后将结果块写入它们自己的文件。这是有效的......虽然我不确定我的实现是如何实现外部排序过程:

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);
   }

 }

}

我的问题是我应该如何将文件分成块?我碰巧确切地知道我的文件有多少行文本,因为我创建了它,所以编写这段代码很容易......但问题实际上告诉你文件的大小;就像在内存中一样,不是文件有多少行文本。我不确定如何将数据分解为“内存块”(以及如何调整它们的大小)而不是文本行。另外,如果我的代码有任何奇怪、错误或不良做法,请告诉我,因为我真的不知道自己在做什么;我只是在努力学习。至于将排序的文件重新合并在一起,我也不知道该怎么做,但我有一个想法。在我寻求这方面的帮助之前,我想尝试一下。谢谢!

4

1 回答 1

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 ;

}
于 2017-01-10T04:32:10.263 回答