Java List.stream.forEach Lambda 表达式中未处理的 IOException
Unhandled IOException Inside Java List.stream.forEach Lambda Expression
我正在使用 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
}
如您所见,方法签名声明抛出所有 IOException,流中的 writeToString 方法有可能抛出 IOException。然而,Java 编译器给我一个错误,指出流线上有一个未处理的 IOException。
为什么流中的异常不会像方法中的任何其他异常一样被抛出?有什么方法可以解决这个问题,而无需在 forEach lambda 表达式中放置 try-catch 语句?
你必须像这样在 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 -> {}。这里的 {} 表示编译器创建新的 Interface (Consumer)
void forEach(Consumer<? super T> action);
和 new Class 实现此接口并将 s 参数传递给它接受 method.Can 您在方法中抛出 new Class 的异常? No.So 你必须尝试捕获 foreach 的每个项目
不要重新发明轮子。使用 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
),仅此而已。您支持 addNewLine
选项的障碍可以通过将所有 String
集为一个来解决,在 addNewLine
是 false
的情况下,因此不会有换行符那么他们之间。否则,Files.write
将向每个字符串附加换行符。
手动处理文件存在性测试或尝试删除或创建文件是没有意义的。无论您是创建自己的 Writer
还是使用 Files.write
,这些实现都会报告有关 existence/non-existence 的失败或通过 IOException
s 创建目标文件的失败尝试,因此您不需要自己做。
更糟糕的是,无论 File.exists()
、File.delete()
或 File.createNewFile()
可能 return,在您随后的 I/O 操作中已经是过时的信息,例如creating/using一个Writer
,不保证后续操作是成功还是失败。
我正在使用 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
}
如您所见,方法签名声明抛出所有 IOException,流中的 writeToString 方法有可能抛出 IOException。然而,Java 编译器给我一个错误,指出流线上有一个未处理的 IOException。
为什么流中的异常不会像方法中的任何其他异常一样被抛出?有什么方法可以解决这个问题,而无需在 forEach lambda 表达式中放置 try-catch 语句?
你必须像这样在 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 -> {}。这里的 {} 表示编译器创建新的 Interface (Consumer)
void forEach(Consumer<? super T> action);
和 new Class 实现此接口并将 s 参数传递给它接受 method.Can 您在方法中抛出 new Class 的异常? No.So 你必须尝试捕获 foreach 的每个项目
不要重新发明轮子。使用 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
),仅此而已。您支持 addNewLine
选项的障碍可以通过将所有 String
集为一个来解决,在 addNewLine
是 false
的情况下,因此不会有换行符那么他们之间。否则,Files.write
将向每个字符串附加换行符。
手动处理文件存在性测试或尝试删除或创建文件是没有意义的。无论您是创建自己的 Writer
还是使用 Files.write
,这些实现都会报告有关 existence/non-existence 的失败或通过 IOException
s 创建目标文件的失败尝试,因此您不需要自己做。
更糟糕的是,无论 File.exists()
、File.delete()
或 File.createNewFile()
可能 return,在您随后的 I/O 操作中已经是过时的信息,例如creating/using一个Writer
,不保证后续操作是成功还是失败。