字节流的异常处理
上述案例中所有的异常都只是进行了抛出处理,这样是不合理的。所以上述代码并不完善,因为异常没有处理。
当我们打开流,读和写,关闭流的时候都会出现异常,异常出现后,后面的代码都不会执行了。假设打开和关闭流出现了异常,那么显然close方法就不会再执行。那么会对程序有什么影响?
案例:
public class IoTest4 { public static void main(String[] args) throws IOException, InterruptedException { String path = "c:\b.txt"; readFile(path); } private static void readFile(String path) throws IOException, InterruptedException { FileInputStream fis = new FileInputStream(path); byte[] byt = new byte[1024]; int len = fis.read(byt); System.out.println(new String(byt, 0, len)); // 让程序睡眠,无法执行到close方法。 Thread.sleep(1000 * 10); fis.close(); } }
在执行该程序的同时我们尝试去删除b.txt文件。如果在该程序没有睡醒的话,我们是无法删除b.txt 文件的。因为b.txt还被该程序占用着,这是很严重的问题,所以一定要关闭流。
目前我们是抛出处理,一旦出现了异常,close就没有执行,也就没有释放资源。那么为了保证close的执行该如何处理呢。
那么就需要使用try{} catch(){}finally{}语句。try中放入可能出现异常的语句,catch是捕获异常对象,fianlly是一定要执行的代码
public class IoTest4 { public static void main(String[] args) throws IOException, InterruptedException { String path = "c:\b.txt"; readFile(path); } private static void readFile(String path) { FileInputStream fis = null; try { fis = new FileInputStream(path); byte[] byt = new byte[1024]; int len = fis.read(byt); System.out.println(new String(byt, 0, len)); } catch (IOException e) { // 抛出运行时异常 throw new RuntimeException(e); } finally { // 把close方法放入finally中保证一定会执行 // 先判断是否空指针 if (fis != null) { try { fis.close(); } catch (Exception e) { throw new RuntimeException(e); } } } } }
文件拷贝的异常处理:
public static void copyFile(String srcPath, String destPath) { FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream(srcPath); fos = new FileOutputStream(destPath); byte[] byt = new byte[1024 * 1024]; int len = 0; while ((len = fis.read(byt)) != -1) { fos.write(byt, 0, len); } } catch (IOException e) { throw new RuntimeException(e); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { throw new RuntimeException(e); } } if (fos != null) { try { fos.close(); } catch (IOException e) { throw new RuntimeException(e); } } } }
注意:
在最后的close代码中可能会有问题,两个close,如果第一个close方法出现了异常,并抛出了运行时异常,那么程序还是停止了。下面的close方法就没有执行到。
那么为了保证close的执行,将第二个放到fianlly中即可。
public static void copyFile(String srcPath, String destPath) { FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream(srcPath); fos = new FileOutputStream(destPath); byte[] byt = new byte[1024 * 1024]; int len = 0; while ((len = fis.read(byt)) != -1) { fos.write(byt, 0, len); } } catch (IOException e) { throw new RuntimeException(e); } finally { try { if (fis != null) { fis.close(); } } catch (IOException e) { throw new RuntimeException(e); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { throw new RuntimeException(e); } } } } }