我正在尝试加载一个包含大量行(>500 万行)的 csv 文件,但是当我试图将它们全部处理成每个值的数组列表时速度会大大降低
我已经尝试了几种不同的读取和从文件加载的输入列表中删除的变体,但它仍然会用完堆空间,即使我为进程分配了 14gb,而文件只有 2gb
我知道我需要删除值,这样我就不会在内存中得到重复的引用,这样我就不会得到一个由行组成的数组列表以及一个由各个逗号分隔值组成的数组列表,但我不知道如何做这样的事情
编辑:作为引用,在这种特定情况下,数据最终应包含 16 * 500 万个值。
如果有更优雅的解决方案,我全力以赴
加载此文件的目的是将其作为数据库处理,并使用适当的方法(例如选择和选择位置),所有这些都由工作表类处理。它与我的 36k 行的较小样本文件一起工作得很好,但我想它不能很好地扩展
当前代码:
//Load method to load it from file
private static CSV loadCSV(String filename, boolean absolute)
{
String fullname = "";
if (!absolute)
{
fullname = baseDirectory + filename;
if (!Load.exists(fullname,false))
return null;
}
else if (absolute)
{
fullname = filename;
if (!Load.exists(fullname,false))
return null;
}
ArrayList<String> output = new ArrayList<String>();
AtomicInteger atomicInteger = new AtomicInteger(0);
try (Stream<String> stream = Files.lines(Paths.get(fullname)))
{
stream.forEach(t -> {
output.add(t);
atomicInteger.getAndIncrement();
if (atomicInteger.get() % 10000 == 0)
{
Log.log("Lines done " + output.size());
}
});
CSV c = new CSV(output);
return c;
}
catch (IOException e)
{
Log.log("Error reading file " + fullname,3,"FileIO");
e.printStackTrace();
}
return null;
}
//Process method inside CSV class
public CSV(List<String> output)
{
Log.log("Inside csv " + output.size());
ListIterator<String> iterator = output.listIterator();
while (iterator.hasNext())
{
ArrayList<String> d = new ArrayList<String>(Arrays.asList(iterator.next().split(splitter,-1)));
data.add(d);
iterator.remove();
}
}
最佳答案
您需要使用为您的任务(选择、分组)提供所需功能的任何数据库。 任何数据库都可以有效读取和聚合 500 万行。 不要尝试使用“对 ArrayList 的操作”,它只适用于小型数据集。
关于java - 使用java加载和处理非常大的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53043826/