问题描述
ListIterator it= FileUtils.lineIterator(bigFile);
List<String> rows = new ArrayList<String>();
//Iterate and add lines to list
while(it.hasNext){
rows.add(it.next())// Exception1
}
//ExecutorService to Iterate a chunk of 20K rows
// In Executor create do validations and create pojo List
// exeutor service to iterate Pojo list and save 20k chunk pojo in mongo db
问题/例外:
1.无法创建名为行的列表,GetoutOfMemory堆异常。
2.如果我不创建列表并处理每一行并存储在mongo中。
这将花费大量时间,并且还可能导致其他异常。
读取和处理如此大文件的最佳方法是什么?
1楼
2 GB的字节将是String
两倍,通常String
将包含char[]
并且char
是两个字节的UTF-16值。
最好是进行一些压缩,如前所述,压缩文件的20 KB块。
还可以为应用程序提供更多内存-DXmax=2g
。
您的代码假定大文件是纯文本(或HTML或SQL转储或日志文件)。
我已经完成了基于行的压缩(效果不是很好,即使对于空行也是如此)。
Path path = Paths.get(bigFile); // String bigFile
Path path = bigFile.toPath(); // File bigFile
Charset charset = Charset.defaultCharset(); // Or whatever the charset is.
List<byte[]> compressedLines = Files.lines(path, charset)
.map(line -> compress(line)) // Or compress(line + "\n")
.collect(Collectors.toList());
byte[] compress(String s) {
byte[] content = s.getBytes(StandardCharsets.UTF_8);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (GZipOutputStream out = new GZipOutputStream(baos)) {
out.write(content);
}
return baos.toByteArray();
}
String decompress(byte[] compressed) {
ByteArrayInputStream bais = new ByteArrayInputStream(compressed);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (GZipInputStream in = new GZipInputStream(bais)) {
byte[] buf = new byte[128];
for (;;) {
int nread = in.read(buf, 0, buf.length);
if (nread <= 0) {
break;
}
baos.write(buf, 0, nread);
}
}
return new String(baos.toByteArray(), StandardCharsets.UTF_8);
}
这可能不是最佳的解决方案。