Unhandled IOException Inside Java List.stream.forEach Lambda Expression

回眸只為那壹抹淺笑 提交于 2021-02-16 09:01:20

问题


I am using the Stream API introduced in Java 8 to run a method for each string in a list.

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
}

As you can see, the method signature states to throw all IOExceptions and the writeToString method inside the stream has the potential to throw an IOException. However, the Java compiler is giving me an error stating that there is an unhandled IOException on the stream line.

Why would the exception inside the stream not get thrown like any other exception inside the method? Is there any way that I can remedy this without putting a try-catch statement in the forEach lambda expression?


回答1:


you have to use try catch in you writeListToFile method like this:

  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
}

why? look at this point s -> {}.Here {} means that compiler make new Interface (Consumer)

 void forEach(Consumer<? super T> action);

and new Class implements this interface and pass s parameter to it's accept method.Can you throw Exception of new Class in your method? No.So you have to try catch of every item of foreach




回答2:


Don’t reinvent the wheel. Use the features offered by the 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 will write all lines of an Iterable (which includes Collections) and that’s it. Your obstacle of supporting the addNewLine option can be solved by collecting all Strings into one in the case, addNewLine is false, hence, there will be no line-feeds between them then. Otherwise, Files.write will append line-feeds to every string.

There is no point in manually dealing with testing for the existence of files or trying to delete or create them. Regardless of whether you create your own Writer or use Files.write, these implementations will already report failures regarding existence/non-existence or failed attempts of creating the target file via IOExceptions, so you don’t need to do it yourself.

Even worse, whatever File.exists(), File.delete(), or File.createNewFile() may return, is already an outdated information upon your subsequent I/O operation, e.g. creating/using a Writer, and does not guaranty anything about whether the subsequent operation will succeed or fail.



来源:https://stackoverflow.com/questions/29838774/unhandled-ioexception-inside-java-list-stream-foreach-lambda-expression

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!