java.io.IOException: Stream Closed

某位刚来不久的实习生,在写一个File文件转Base64编码的项目过程中,需要关闭IO流,看他代码实在太长,就给了工具类,这篇幅里有讲,详见链接:https://blog.csdn.net/weixin_39309402/article/details/101447275
结果他执行代码的时候,发现文件内容为Null,就问我为什么?我先把代码贴上:

public class Base64ToString {

	/**
	 *
	 * @param path
	 * @return String
	 * @description 将文件转base64字符串
	 */
	public static String fileToBase64(String path) {
		String base64 = null;
		InputStream in = null;
		try {
			File file = new File(path);
			in = new FileInputStream(file);
			byte[] bytes = new byte[(int) file.length()];
			in.read(bytes);

			base64 = Base64.getEncoder().encodeToString(bytes);
		} catch (Exception e) {
			System.out.println("" + e.getMessage());
		} finally {
			IOCloseUtil.close(in);
		}
		return base64;
	}

	/**
	 *
	 * @param destPath
	 *            存储路径
	 * @param fileName
	 *            存储文件名
	 * @param String
	 *            Base64编码字符串
	 * @description BASE64解码成File文件
	 */
	public static void base64ToFile(String destPath, String base64, String fileName) {
		File file = null;
		File dir = new File(destPath);
		if (!dir.exists() && !dir.isDirectory()) {
			dir.mkdirs();
		}
		BufferedOutputStream bos = null;
		java.io.FileOutputStream fos = null;
		try {
			byte[] bytes = Base64.getDecoder().decode(base64);
			file = new File(destPath + File.separator + fileName);
			fos = new java.io.FileOutputStream(file);
			bos = new BufferedOutputStream(fos);
			bos.write(bytes);
		} catch (Exception e) {
			System.out.println("" + e.getMessage());
		} finally {
			IOCloseUtil.close(fos, bos);
		}
	}

	public static void main(String[] args) {
		// String base64Str = fileToBase64("H:\\Music\\123.txt");
		// System.err.println(base64Str);

		base64ToFile("H:\\Music", "5Z2a5oyB5piv5pmu6YCa5Lq66YCa5ZCR5p+Q5Liq6aKG5Z+f55qE5ZSv5LiA6YCU5b6E", "newM.sql");
		System.out.println("success");
	}

}

结果newM.sql文件内容竟是0字节,而控制台输出如下:

这种情况我以前也遇见过,今天就顺道讲讲,其实IO流关闭是有顺序讲究的,我让他把IOCloseUtil.close(fos, bos)改成IOCloseUtil.close(bos, fos)结果问题就顺利解决了,他问我是什么原因?因为未使用工具类以前,他的IO流关闭是这样的,测试也没问题,所以他还怀疑可能是IO流关闭工具类的问题:

if (bos != null) {
				try {
					bos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

我让他改一下顺序,先关闭fos,在关闭bos,结果执行就这样了:

所以,在关闭IO流时,一般讲究这样的顺序:后打开的先关闭,先打开的后关闭!

另外一种情况是跟依赖有关:依赖者先关闭,被依赖者后关闭!

比如如果流a依赖流b,应该先关闭流a,再关闭流b。例如字节流bos依赖字节流fos,应该先关闭bos,再关闭fos,不然会抛出IO异常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值