我正在阅读一些非常大的文本文件并遇到Java - Char Buffer Issue中描述的错误。
当我有一个非常大的文件(> 1gb)时,Charset.defaultCharset().decode(ByteBuffer bb).toString()
会抛出一个IllegalArgumentException
。大概是因为缓冲容量溢出并变成负数。
这是我一直在使用的啜食功能:
public static String slurp(File f) throws IOException, FileNotFoundException
{
FileInputStream fis = new FileInputStream(f);
try{
FileChannel fc = fis.getChannel();
MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
//The decode method on the following line throws the IllegalArgumentException
return Charset.defaultCharset().decode(bb).toString();
}finally{
fis.close();
}
}
我想简单地为此函数添加错误处理,以便在抛出异常时使用另一种更安全的方法,例如How do I create a Java string from the contents of a file?中的问题语句中的模式
例如,
public static String slurp(File f) throws IOException, FileNotFoundException
{
FileInputStream fis = new FileInputStream(f);
try{
FileChannel fc = fis.getChannel();
MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
return Charset.defaultCharset().decode(bb).toString();
} catch (IllegalArgumentException e) {
// This exception is thrown by extremely large files
BufferedReader reader = new BufferedReader(new FileReader(f));
String line = null;
StringBuilder stringBuilder = new StringBuilder();
String ls = System.getProperty("line.separator");
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append(ls);
}
return stringBuilder.toString();
}finally{
fis.close();
}
}
另一种方法是在同一个问题上使用效率最高的建议答案。
public static String slurp(File f) throws IOException, FileNotFoundException
{
FileInputStream fis = new FileInputStream(f);
try{
FileChannel fc = fis.getChannel();
MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
return Charset.defaultCharset().decode(bb).toString();
} catch (IllegalArgumentException e) {
// This exception is thrown by extremely large files
List<String> lines = Files.readAllLines(f.toPath(), Charset.defaultCharset());
return String.join("/n", lines);
}finally{
fis.close();
}
}
任何大文件在内存时都会变得很麻烦,而不是流式传输,但有没有理由更喜欢这两种方法中的一种或其他什么?
我问,因为问题的接受答案讨论了两个答案解决方案的内存利用率,而不是提问者的示例模式。