如何解析1.2GB
这样的大文件,其中文件中的总行数为36259190
。如何将每一行解析为一个对象并将其保存在列表中。
我每次都会得到OutOfMemmoryError
。
List<Point> points = new ArrayList<>();
public void m2() throws IOException {
try (BufferedReader reader = Files.newBufferedReader(Paths.get(DATAFILE))) {
reader.lines().map(s -> s.split(","))
.skip(0)
.forEach(p -> points.add(newPoint(p[0], p[1], p[2])));
}
}
class Point {
String X;
String Y;
String Z;
}
答案 0 :(得分:1)
您需要使用命令行参数-Xms(最小内存)-Xmx(最大内存)。
示例:
-Xmx4G (4GB)
-Xmx200M (200MB)
java -jar program.jar -Xmx8G
答案 1 :(得分:1)
Shiro的回答是正确的,为Java分配更多内存。
如果你买不起内存,那就用一个数据库吧。例如,Postgres或H2。
数据库的目的之一是将数据保存到存储,同时有效地处理查询内存并根据需要加载数据。
在读取数据文件的每一行时,请立即存储在数据库中。稍后查询所需记录。仅在内存中为来自该查询结果集的所需行实例化对象。
答案 2 :(得分:1)
关注您的数据类型。我很确定你的观点不包含三个文本片段。因此,请根据实际类型定义Point
的字段,例如使用int
或double
。这些原始数据类型比String
表示消耗的内存要少得多。
class Point {
double x, y, z;
Point(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
Point(String x, String y, String z) {
this.x = Double.parseDouble(x);
this.y = Double.parseDouble(y);
this.z = Double.parseDouble(z);
}
}
然后将您的数据文件收集为
public List<Point> m2() throws IOException {
try(BufferedReader reader = Files.newBufferedReader(Paths.get(DATAFILE))) {
return reader.lines().map(s -> s.split(","))
.map(a -> new Point(a[0], a[1], a[2]))
.collect(Collectors.toList());
}
}
然后,正如其他人所说,关心为JVM分配的内存。使用上面的point类,你可以使用~1½GiB的堆来处理36个Mio实例而没有问题......