前言
本文将上一节做的代码,对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();
}
}
}