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