2

我的程序读取各种大小的文本文件。然后它从文本文件中获取数字并根据数字创建数组列表。我计划使用的最大文件是 286,040 KB。当我运行我的程序并读取文件时,我的程序停止工作。

我如何知道我的 java 程序可以处理的最大大小是多少?有没有办法计算我的java程序可以处理多大的文件?

另外,让我的程序能够容纳如此大的数组列表的最佳建议是什么?但是,我听说过哈希表。我无法完全理解这个概念。

根据请求,我添加了上传文件的方式:

String name = getFileName();
Scanner scanDaily = new Scanner(new File(name));

public static String getFileName()
{ //getFileName
    Scanner getName = new Scanner (System.in);
    System.out.println("Please input File Name");
    String fileName = getName.nextLine();
    return fileName;    
}  //getFileName

更新:感谢那些回答的人,它非常有帮助

新问题

我现在想将文件中的数字读入arraylist

          String name = getFileName();
    FileReader f= new FileReader(new File(name));
        BufferedReader bf=new BufferedReader(f);
        Scanner sc=new Scanner(bf);

    ArrayList<Double> ID = new ArrayList<Double>();
    ArrayList<Double> Contract = new ArrayList<Double>();
    ArrayList<Double> Date = new ArrayList<Double>();
    ArrayList<Double> Open = new ArrayList<Double>();
    ArrayList<Double> High = new ArrayList<Double>();
    ArrayList<Double> Low = new ArrayList<Double>();
    ArrayList<Double> Close = new ArrayList<Double>();
    ArrayList<Double> Volume = new ArrayList<Double>();

    int rows = 8;
    int counter1 = 0;

    //Update code to prompt user for file
    ArrayList<Double> list = new ArrayList<Double>();

    while (scanDaily.hasNext())
    { //while
        double value = scanDaily.nextDouble();
        DecimalFormat df = new DecimalFormat("#.#####");
        df.format(value);
        list.add(value);
    }  //while

在我使用扫描仪读取文件之前,该扫描仪被命名为scandaily。现在我有一个文件阅读器和一个缓冲阅读器,我用哪一个来浏览我的 txt 文件?

4

6 回答 6

6

您真的需要将整个文件保存在内存中吗?

对于简单的治疗,您应该考虑使用BufferedReader,尤其是BufferedReader.readLine

您可以对文件的每一行执行操作,因此您不再需要加载整个文件。

于 2013-06-11T12:32:51.207 回答
2

您可以通过以下方式增加 JVM 的最大内存大小

$ java -Xmx1024m ....

但您可能希望更有效地读取和存储这些数据。例如,您是否将完整的文件读入内存,然后解析/转换为整数列表?如果是这样,为什么不简单地读取和解析每一行而不将完整的文件保存在内存中。

例如,请参阅此答案以获取更多信息。

于 2013-06-11T12:27:06.923 回答
1

当我运行我的程序并读取文件时,我的程序停止工作。

我认为问题会是这样,并在您添加代码后确认。我以前也遇到过类似的问题。

Scanner直接与File导致问题的对象一起使用。因为那没有缓冲。改为使用BufferedReader。直接使用带有大文件对象的扫描仪被证明是失败的。因为,我猜这不是缓冲的。

Scanner scanDaily = new Scanner(new File(name));  //problematic for big files.

使用BufferedReaderwith usingFileReader而不是 that。它根据需要缓冲文件中的数据,但不是一次。

例子:

     import java.io.BufferedReader;
     import java.io.FileReader;
     import java.util.Scanner;
     import java.io.File;
     ...............
     FileReader f=new FileReader(new File(fileName));
     BufferedReader bf=new BufferedReader(f);
     Scanner sc=new Scanner(bf);

所以你的代码现在变成:

     String name = getFileName();
     FileReader f= new FileReader(new File(name));
     BufferedReader bf=new BufferedReader(f);
     Scanner sc=new Scanner(bf);

您的程序与您的扫描仪代码一起挂起,因为它会将您的大文件一次全部加载到内存中,因此需要时间。

另外,让我的程序能够容纳如此大的数组列表的最佳建议是什么?但是,我听说过哈希表。我无法完全理解这个概念。

在这种情况下,由于文件大小很大。我建议您使用内存映射文件。因此,您可以将文件映射到内存中并像数组一样使用它来访问它。请参阅有关 java 中的内存映射的此链接。

看来你已经知道了ArrayLists

我将简要介绍一下HashMapHashMap使用键值对来存储数据,您有基于该键来存储值的键。您将使用密钥来存储数据并获取数据。

例子:

          HashMap<KeyType,ValueType> hm=new HashMap<KeyType,ValueType>

所以这种方式你可以使用任何类型作为键和任何类型作为值。

          HashMap<Integer,String> hm = new HashMap<Integer,String>
          hm.set(0,"hello");
          hm.set(5,"bello");

          HashMap<String,String> sm=new HashMap<String,String>
          sm.set("USA","United States of America");
          sm.set("UK","United Kingdom");
          sm.set("IND","India");
          sm.set("AUS","Australia");              

          so, you can query `sm.get("AUS")` to get `"Australia"`,

决定使用哪种数据结构:何时在 LinkedList 或 ArrayList 上使用 HashMap,反之亦然

我希望这能解决问题。

于 2013-06-11T13:01:10.977 回答
0

如果您存储数字,int您可以将数字写入内存映射文件 (java.nio) Int Buffer。取决于使用场景。

固定的超大尺寸int[]可能是可行的。

于 2013-06-11T12:35:43.843 回答
0

您可以尝试增加 JVM 的内存分配。 检查这篇文章。如果您的程序在得出结论之前挂起,还请尝试跟踪您得到的确切异常/错误。

于 2013-06-11T12:31:20.053 回答
0

由于您使用的最大文件大小 < 3 GB,并且我假设您在 RAM 大于 3 GB 的机器上运行它,您可以使用以下参数运行程序

java -Xmx3046m -jar yourjarname.jar
于 2013-06-11T12:28:03.843 回答