文件大小对于java来说太大了

时间:2013-06-11 12:25:31

标签: java memory

我的程序读取各种大小的文本文件。然后它从文本文件中获取数字并根据数字创建数组列表。我计划使用的最大文件是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文件?

6 个答案:

答案 0 :(得分:6)

你真的需要将整个文件留在内存中吗?

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

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

答案 1 :(得分:2)

您可以通过以下内容increase the max memory size of the JVM

$ java -Xmx1024m ....

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

e.g。有关详细信息,请参阅this answer

答案 2 :(得分:1)

  

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

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

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

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

使用BufferedReader而不是使用FileReader。它根据需要缓存文件中的数据,但不能立即缓存。

示例:

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

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

  

此外,有什么最好的建议使我的程序能够   持有如此大尺寸的数组列表?我听说过哈希表,   然而;我无法完全理解这个概念。

在这种情况下,由于文件大小很大。我建议你使用内存映射文件。因此,您可以将文件映射到内存中并使用它像数组一样访问它。 See this link about memory mapping in java.

您似乎已经了解ArrayLists

我将简要介绍HashMap:     HashMap使用键值对来存储数据,您可以根据值存储该键。您将使用密钥存储数据并获取数据。

示例:

          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"`,

决定使用哪种数据结构:When to use HashMap over LinkedList or ArrayList and vice-versa

我希望这能解决问题。

答案 3 :(得分:0)

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

java -Xmx3046m -jar yourjarname.jar

答案 4 :(得分:0)

您可以尝试增加JVM的内存分配。 Check this post。 如果您的程序在得出结论之前挂起,还要尝试跟踪您获得的确切异常/错误。

答案 5 :(得分:0)

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

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