10 IO流(七)——copy方法封装、关闭流方法封装的两种方式以及try...with...resource
前言
本文将上一节做的代码,对copy方法与关闭流方法进行封装,并使用try...with...resource关闭流。
copy方法封装
我们将copy方法封装,使得只需传入两个流,就能将输入流的源文件copy到输出流的目的文件。
值得注意的是,由于ByteArrayOutputStream不能直接写入文件,调用此方法后,数据保存在流中。
流关闭方法封装
方法一:原始方法
最原始的方法莫过于try...catch与close()结合
public static void close(InputStream is,OutputStream os){ try{ if(null!=os){ os.close(); } }catch(IOException e){ e.printStackTrace(); } try{ if(null!=is){ is.close(); } }catch(IOException e){ e.printStackTrace(); } }
方法二:多流关闭
使用方法的可变参数,通过遍历的方法,一个个关闭流。
public static void close(Closeable...ios){ for(Closeable io : ios){ try{ io.close(); }catch(IOException e){ e.printStackTrace(); } } }
方法三:try...with...resource语法糖
在jdk1.7开始,就可以使用try...with...resource方法进行处理那些实现了Autocloseable的类或对象。它的格式是:
try(xxx cc = new xxx()){
}catch(...){...}
public static void copy2(String filePath,String destPath){ //操作流 try(InputStream is = new FileInputStream(filePath); OutputStream os = new FileOutputStream(destPath)){//没有先后顺序 byte[] flush = new byte[1024*10];//缓冲池 int len = -1;//接收单次读取的长度 while((len = is.read(flush))!=-1){//读取数据 os.write(flush,0,len);//写入数据 } os.flush();//刷新 }catch(IOException e){ e.printStackTrace(); }//这里无需关闭方法 }
写在try后的小括号中,如果有多个,用英文分号分隔。在括号中写完整的流声明,在执行完try后将自动关闭流。
在jdk1.9中进行了升级:可以不用xxx cc =new xxx()的方式,而是直接传入对象即可,格式为:
try(object1;object2...){..}catch(...){...}
同样可以传多个对象。需要注意的是,传入的对象必须被final修饰!
public static void copy2(String srcPath,String destPath){ //选择流 FileInputStream fis =null; FileOutputStream fos = null; try{ fis = new FileInputStream(srcPath); fos = new FileOutputStream(destPath); }catch(IOException e){ e.printStackTrace(); } final InputStream is = new BufferedInputStream(fis);//需要是final修饰才行 final OutputStream os = new BufferedOutputStream(fos); //操作 try(is;os){//看这里!语法糖! byte[] flush = new byte[1024]; int len = -1; while((len = is.read(flush))!=-1){//读入 os.write(flush,0,len);//写出 os.flush();//刷新 } }catch(IOException e){ e.printStackTrace(); } }
关于本文的完整练习代码
import java.io.*; public class IOTest01 { public static void main(String[] args) { //文件源 String src = "1.rar"; String dest = "1_cp.rar"; //计算copy花费的时间 long l1 = System.currentTimeMillis(); copy2(src,dest); long l2 = System.currentTimeMillis(); long time = l2-l1; System.out.println(time); } public static void copy(String srcPath,String destPath){ //选择流 //操作 try(InputStream is = new BufferedInputStream(new FileInputStream(srcPath)); OutputStream os = new BufferedOutputStream(new FileOutputStream(destPath))){ byte[] flush = new byte[1024]; int len = -1; while((len = is.read(flush))!=-1){//读入 os.write(flush,0,len);//写出 } os.flush();//刷新 }catch(IOException e){ e.printStackTrace(); } } //下面是jdk1.9以后语法糖关闭流的使用 public static void copy2(String srcPath,String destPath){ //选择流 FileInputStream fis =null; FileOutputStream fos = null; try{ fis = new FileInputStream(srcPath); fos = new FileOutputStream(destPath); }catch(IOException e){ e.printStackTrace(); } final InputStream is = new BufferedInputStream(fis);//需要是final修饰才行 final OutputStream os = new BufferedOutputStream(fos); //操作 try(is;os){//看这里!语法糖! byte[] flush = new byte[1024]; int len = -1; while((len = is.read(flush))!=-1){//读入 os.write(flush,0,len);//写出 os.flush();//刷新 } }catch(IOException e){ e.printStackTrace(); } } }