Java 如何在Iterable.forEach中处理IOException?

Java 如何在Iterable.forEach中处理IOException?,java,foreach,lambda,java-8,checked-exceptions,Java,Foreach,Lambda,Java 8,Checked Exceptions,我正在研究将一组对象写入文件的方法。为什么下面使用Iterable.forEach()的实现无法编译?在Eclipse中,我得到的消息是没有处理IOException。这尤其令人困惑,因为我似乎正在处理IOException public void write(Iterable<?> objects) { try (BufferedWriter bw = new BufferedWriter( new OutputStreamWriter(

我正在研究将一组对象写入文件的方法。为什么下面使用Iterable.forEach()的实现无法编译?在Eclipse中,我得到的消息是没有处理IOException。这尤其令人困惑,因为我似乎正在处理IOException

  public void write(Iterable<?> objects) {
    try (BufferedWriter bw = new BufferedWriter(
        new OutputStreamWriter(
            new FileOutputStream("out.txt"), "UTF-8"));) {

      objects.forEach((o) -> bw.write(o.toString())); //Unhandled exception type IOException

  } catch (IOException e) {
    //handle exception
  }
}

我已经检查了和文档,它们似乎都没有建议如何解决这个问题。

问题是接口
消费者
中的方法
accept
没有声明抛出异常。因此,不能使用在lambda中引发选中异常的方法

解决方案是为每个循环使用一个

让我们以匿名类的形式编写lambda:

objects.forEach(new Consumer<Object>() {
    public void accept(Object o) {
        bw.write(o.toString());
    }
});
(另见。)

保证像该示例中那样包装和抛出异常有效:

操作引发的异常将转发给调用方


但是,最好不要在抛出选中异常的上下文中使用
forEach
,或者在lambda的主体中捕获并处理异常。

如果您只关心将字符串打印到文件中,使用
PrintStream
PrintWriter
代替其他
Writer
类。
PrintStream
PrintWriter
的显著特点是它们的打印操作不会抛出
IOException
。它们还自动调用对象上的
toString
,这使事情变得非常方便:

public void write1(Iterable<?> objects) {
    try (PrintStream ps = new PrintStream("printout.txt", "UTF-8")) {
        objects.forEach(ps::println);
    } catch (IOException ioe) {
        // handle
    }
}
现在我们需要编写一个函数,将
IOConsumer
转换为
Consumer
。它通过将捕获的任何
IOException
转换为一个
UncheckedIOException
,这是一个为此目的创建的异常

static <T> Consumer<T> wrap(IOConsumer<? super T> ioc) {
    return t -> {
        try {
            ioc.accept(t);
        } catch (IOException ioe) {
            throw new UncheckedIOException(ioe);
        }
    };
}
静态使用者包装(IOConsumer对象){
try(BufferedWriter bw=new BufferedWriter(
新的OutputStreamWriter(
新文件输出流(“out.txt”),“UTF-8”)){
forEach(wrap(o->bw.write(o.toString()));
}捕获(IOException |未选中异常e){
//处理异常
}
}

通常,如果发生任何异常,我们不会将数据写入文件。记住这一点,我们可以编写自己的
消费者,将选中的异常包装为未选中的异常
。这样就可以避免编译时错误。 请尝试下面的代码

import java.io.*;
import java.util.*;
public class HelloWorld{

     public static void main(String []args){
        write(Arrays.asList(1,2,3));
     }

  public static void write(Iterable<?> objects) {
    try (BufferedWriter bw = new BufferedWriter(
        new OutputStreamWriter(
            new FileOutputStream("c:\\out.txt"), "UTF-8"))) {

      objects.forEach(o->myConsumerThrowsRuntimeException(bw,o.toString())); //Unhandled exception type IOException

  } catch (Exception e) {
    //handle exception
  } 
  }
  public static void myConsumerThrowsRuntimeException(Writer writer , String data){
      try{
          writer.write(data);
      }catch(IOException e){

          throw new RuntimeException("Cannot write Data error is "+e.getMessage());
      } 
  } 
}
import java.io.*;
导入java.util.*;
公共类HelloWorld{
公共静态void main(字符串[]args){
写(Arrays.asList(1,2,3));
}
公共静态无效写入(Iterable对象){
try(BufferedWriter bw=new BufferedWriter(
新的OutputStreamWriter(
新文件输出流(“c:\\out.txt”),“UTF-8”)){
objects.forEach(o->myConsumerThrowsRuntimeException(bw,o.toString());//未处理的异常类型IOException
}捕获(例外e){
//处理异常
} 
}
公共静态void myConsumerThrowRuntimeException(编写器、字符串数据){
试一试{
writer.write(数据);
}捕获(IOE异常){
抛出新的RuntimeException(“无法写入数据错误为”+e.getMessage());
} 
} 
}

您能通过命令行编译它吗?eclipse的哪个版本?唉,这是当前lambda实现的缺点之一,我已经不止一次地抨击过它了!:)这就是我要找的。谢谢
interface IOConsumer<T> {
    void accept(T t) throws IOException;
}
static <T> Consumer<T> wrap(IOConsumer<? super T> ioc) {
    return t -> {
        try {
            ioc.accept(t);
        } catch (IOException ioe) {
            throw new UncheckedIOException(ioe);
        }
    };
}
public void write2(Iterable<?> objects) {
    try (BufferedWriter bw = new BufferedWriter(
             new OutputStreamWriter(
                 new FileOutputStream("out.txt"), "UTF-8"))) {
        objects.forEach(wrap(o -> bw.write(o.toString())));
    } catch (IOException|UncheckedIOException e) {
        //handle exception
    }
}
import java.io.*;
import java.util.*;
public class HelloWorld{

     public static void main(String []args){
        write(Arrays.asList(1,2,3));
     }

  public static void write(Iterable<?> objects) {
    try (BufferedWriter bw = new BufferedWriter(
        new OutputStreamWriter(
            new FileOutputStream("c:\\out.txt"), "UTF-8"))) {

      objects.forEach(o->myConsumerThrowsRuntimeException(bw,o.toString())); //Unhandled exception type IOException

  } catch (Exception e) {
    //handle exception
  } 
  }
  public static void myConsumerThrowsRuntimeException(Writer writer , String data){
      try{
          writer.write(data);
      }catch(IOException e){

          throw new RuntimeException("Cannot write Data error is "+e.getMessage());
      } 
  } 
}