我正在使用Java 8中引入的Stream API为列表中的每个字符串运行一个方法。
public boolean initFile() throws IOException
{
if (this.outFile.exists()) {
this.outFile.delete();
}
return this.outFile.createNewFile();
}
public void writeStringToFile(String str, boolean addNewLine) throws IOException
{
if (this.mode != FileMode.READ) {
if (this.initFile()) {
FileWriter fileWriter;
if (this.mode == FileMode.APPEND)
fileWriter = new FileWriter(outFile.getAbsolutePath(), true);
else
fileWriter = new FileWriter(outFile.getAbsolutePath());
fileWriter.write(str);
if (addNewLine)
fileWriter.write("\n");
fileWriter.close();
} else {
throw new IOException("IO Error: The file could not be initialized.");
}
} else {
throw new IOException("Cannot write to a file with the mode FileMode.READ");
}
}
public void writeListToFile(List<String> strings, boolean addNewLine) throws IOException
{
strings.stream().forEach(s -> this.writeStringToFile(s, addNewLine)); // Unhandled IOException from writeStringToFile
}
如您所见,方法签名声明抛出所有IOExceptions,并且流内的writeToString方法可能会抛出IOException。但是,Java编译器给出了一个错误,指出流线上存在未处理的IOException。
为什么流中的异常不会像方法中的任何其他异常一样被抛出?有没有办法在不在forEach lambda表达式中放入try-catch语句的情况下解决这个问题?
答案 0 :(得分:3)
不要重新发明轮子。使用Java API提供的功能。
public void writeListToFile(List<String> strings, boolean addNewLine) throws IOException
{
if(this.mode == FileMode.READ)
throw new IOException("Cannot write to a file with the mode FileMode.READ");
Files.write(outFile.toPath(), addNewLine? strings:
Collections.singleton(strings.stream().collect(Collectors.joining())),
this.mode==FileMode.APPEND? StandardOpenOption.APPEND: StandardOpenOption.CREATE);
}
Files.write
会写出Iterable
的所有行(包括Collection
s),就是这样。支持addNewLine
选项的障碍可以通过将String
收集到一个案例中来解决,addNewLine
是false
,因此,不会有换行符他们之间。否则,Files.write
会将换行符附加到每个字符串。
手动处理测试是否存在文件或尝试删除或创建文件是没有意义的。无论您是创建自己的Writer
还是使用Files.write
,这些实现都会报告有关存在/不存在的失败或通过IOException
创建目标文件失败的尝试,因此您不需要自己动手。
更糟糕的是,无论File.exists()
,File.delete()
或File.createNewFile()
可能返回,在您后续的I / O操作中已经是过时的信息,例如创建/使用Writer
,并不保证后续操作是成功还是失败。
答案 1 :(得分:2)
你必须在writeListToFile方法中使用try catch,如下所示:
public void writeListToFile(List<String> strings, boolean addNewLine) throws Exception {
strings.stream().forEach(s -> {
try {
writeStringToFile(s, addNewLine);
} catch (IOException ex) {
//you can Log it immediately or throw ex;
Logger.getLogger(C.class.getName()).log(Level.SEVERE, null, ex);
}
});
// Unhandled IOException from writeStringToFile
}
为什么呢? 看看这一点s - &gt; {} .Here {}表示编译器创建新的Interface(消费者)
void forEach(Consumer<? super T> action);
并且新类实现了这个接口并将s参数传递给它的accept方法。你可以在方法中抛出新类的异常吗?不。所以你必须尝试抓住每个foreach项目