You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Stream API与Lambda创建FileOutputStream时出错,求解决方法

问题:使用Stream API操作FileOutputStream时写入第二个元素触发异常

我用FileOutputStream创建文件,用普通for循环可以正常执行:

public class EjemploFileOutputStream {

/**
 * @param args
 */
public static void main(String[] args) {
    
    OutputStream fOut = null;
    
    try {
        fOut = new FileOutputStream("primero.dat");
        for(int i = 0; i < 1000; i++) {
            fOut.write(i);
        }           
    } catch (FileNotFoundException e) {         
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (fOut != null)
            try {
                fOut.close();
            } catch (IOException e) {                   
                e.printStackTrace();
            }
    }
}
}

但改用Stream API和Lambda表达式时出现错误,代码如下:

public class EjemploFileOutputStream {

static OutputStream fOut2 = null;

/**
 * @param args
 * @throws FileNotFoundException 
 */
public static void main(String[] args) throws FileNotFoundException {
  
    List<Number> cantidades = Arrays.asList(10, 20, 30, 40, 50);
    try {
        fOut2 = new FileOutputStream("primero3.dat");
    } catch (FileNotFoundException e1) {            
        e1.printStackTrace();
    }
    cantidades.stream().map(cantidad->cantidad.intValue()).forEach(cantidad -> {
        try {
            fOut2.write(cantidad);

        } catch (IOException e1) {
            e1.printStackTrace();
        } finally {
            if (fOut2 != null)
                try {
                    fOut2.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
    });
}
}

错误现象

  • 列表第一个值(10)能正常写入文件
  • 处理第二个值(20)时触发IOException,提示流已经关闭

问题原因

你在forEach的Lambda表达式里,把关闭流的逻辑写在了finally块中——这意味着每处理一个元素就会关闭一次流。第一个元素写完后流已经被关闭,第二个元素再调用write时,自然会触发流已关闭的异常。

解决方法

把关闭流的逻辑移到forEach外面,和普通for循环的写法保持一致,只在所有元素写完后关闭一次流:

修正后的代码

public class EjemploFileOutputStream {

/**
 * @param args
 */
public static void main(String[] args) {
    OutputStream fOut2 = null;
    List<Number> cantidades = Arrays.asList(10, 20, 30, 40, 50);
    
    try {
        fOut2 = new FileOutputStream("primero3.dat");
        cantidades.stream()
                  .map(Number::intValue)
                  .forEach(cantidad -> {
                      try {
                          fOut2.write(cantidad);
                      } catch (IOException e) {
                          e.printStackTrace();
                      }
                  });
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {
        if (fOut2 != null) {
            try {
                fOut2.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
}

更优写法:使用try-with-resources(自动关流)

Java 7及以上推荐用try-with-resources语法,它会自动在代码块结束后关闭流,无需手动写finally,更简洁安全:

public class EjemploFileOutputStream {

/**
 * @param args
 */
public static void main(String[] args) {
    List<Number> cantidades = Arrays.asList(10, 20, 30, 40, 50);
    
    try (OutputStream fOut2 = new FileOutputStream("primero3.dat")) {
        cantidades.stream()
                  .map(Number::intValue)
                  .forEach(cantidad -> {
                      try {
                          fOut2.write(cantidad);
                      } catch (IOException e) {
                          e.printStackTrace();
                      }
                  });
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
}

内容的提问来源于stack exchange,提问作者Angel Picallo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 05:35:29