win32判断文件是否拷贝完毕_JavaIO流中的拷贝

838e2821465677f45670156116b66e69.png

JavaIO流中对数据的操作尤为重要,掌握了基本的拷贝操作,才能将各种数据源的操作联系起来。

先来看看对文件夹的拷贝吧:

/**
 * 利用递归实现文件夹的拷贝操作
 * 分析:判断
 * 	是文件:调用拷贝文件的方法fileCopy(...)
 * 	是文件夹:创建文件夹,并使用递归实现子文件夹/子文件的判断及操作
 * @param src:要拷贝的文件夹源头
 * @param dest:要拷贝到的文件夹源头
 */
public static void dirCopy(File src,File dest) {
	if(src.isFile()) { //是文件
		fileCopy(src, dest);
	}else { //是文件夹
		dest.mkdirs();
		for(File subSrc:src.listFiles()) { //遍历子文件夹/子文件
			dirCopy(subSrc, new File(dest,subSrc.getName()));
		}
	}
}

对文件的拷贝,我们可以这样写:

/**
 * 实现文件的拷贝
 * 	输入流读取的同时输出流进行写出
 * @param src:要拷贝的文件源头
 * @param dest:要拷贝到的文件源头
 */
public static void fileCopy(File src,File dest) {
	//1.创建源
	//2.选择流
	InputStream is = null;
	OutputStream os = null;
	try {
		is = new FileInputStream(src);
		os = new FileOutputStream(dest);
		//3.操作:分段读取并写出
		int len; //接收长度
		byte[] flush = new byte[1024]; //缓冲容器,一次读写1k
		while((len=is.read(flush))!=-1) {
			os.write(flush, 0, len);
		}
		os.flush(); //写完手动刷新,避免数据在缓冲容器中(当然当流关闭时会自动刷新)
	}catch(FileNotFoundException e) {
		e.printStackTrace();
	}catch(IOException e) {
		e.printStackTrace();
	}finally {
		//4.关闭流,分别关闭,先打开的后关闭
		try {
			if(os!=null) {	//判断是否为空,避免空指针异常
				os.close();
			}
		}catch(IOException e) {
			e.printStackTrace();
		}
		try {
			if(is!=null) { //判断是否为空,避免空指针异常
				is.close();
			}
		}catch(IOException e) {
			e.printStackTrace();
		}
	}
}

以上代码只能实现对文件的拷贝操作,当然适合于拷贝任何格式的数据文件,包括视频、音频、图片等等。但是如果我想将一张图片拷贝到字节数组中呢(这里的字节数组相当于内存),也就是说从文件到字节数组,或着是从字节数组到文件。那么以上代码就具有局限性了,也不易于扩展,来看以下代码:

/**
 * 对接流
 * @param is:输入流
 * @param os:输出流
 */
public static void copy(InputStream is,OutputStream os) {
	//1.创建源
	//2.选择流
	try {
		//3.操作
		byte[] flush = new byte[1024]; //缓冲容器
		int len; //接收长度
		while((len=is.read(flush))!=-1) {
			os.write(flush, 0, len);
		}
		os.flush();
	}catch(FileNotFoundException e) {
		e.printStackTrace();
	}catch(IOException e) {
		e.printStackTrace();
	}finally {
		try {
			if(os!=null) {
				os.close();
			}
		}catch(IOException e) {
			e.printStackTrace();
		}
		try {
			if(is!=null) {
				is.close();
			}
		}catch(IOException e) {
			e.printStackTrace();
		}
	}
}

嗯,这样就可以实现以上要求了,但是我们发现:关闭资源的操作一直在,而且都一样,我们可以封装一下,这样在finally中就可以直接调用了。

/**
 * 关闭的方法
 * @param is:输入流
 * @param os:输出流
 */
public static void close(InputStream is,OutputStream os) {
	try {
		if(os!=null) {
			os.close();
		}
	}catch(IOException e) {
		e.printStackTrace();
	}
	try {
		if(is!=null) {
			is.close();
		}
	}catch(IOException e) {
		e.printStackTrace();
	}
}

好了,看看封装的代码,幸亏只有两个流,要是流很多咋办,形参太多,但是我们发现输入流InputStream和输出流OutputStream都实现了同一个接口:Closeable。嗯,这样,我们可以试试JDK1.5的新特性:可变参数。

/**
 * 封装的关闭方法
 * @param ios:要关闭的流
 */
public static void close(Closeable... ios) {
	for(Closeable io:ios) {
		try {
			if(io!=null) {
				io.close();
			}
		}catch(IOException e) {
			e.printStackTrace();
		}
	}
}

现在看似完美了,但我还不太满意,有时候,我觉得手动关闭资源太麻烦了。别急,来看看JDK1.7的新特性:try...with...resources(自动关闭资源)。

/**
 * JDK1.7之后的新特性 try...with...resources:自动关闭资源
 * 文件的拷贝
 * @param srcPath:要拷贝的源头
 * @param destPath:要拷贝到的目的地
 */
public static void copy1(String srcPath,String destPath) {
	//1.创建源
	File src = new File(srcPath);
	File dest = new File(destPath);
	//2.选择流
	try(InputStream is = new FileInputStream(src);
		OutputStream os = new FileOutputStream(dest)) {
		//3.操作
		byte[] flush = new byte[1024]; //缓冲容器
		int len; //接收长度
		while((len=is.read(flush))!=-1) {
			os.write(flush, 0, len);
		}
		os.flush();
	}catch(FileNotFoundException e) {
		e.printStackTrace();
	}catch(IOException e) {
		e.printStackTrace();
	}
}

大家发现:try里面写的好繁琐,别急,看看JDK1.9的改进版(不过要求你所要关闭的资源是final或等效于final的变量)。

/**
 * JDK1.9之后对 try...with...resources的改进
 * 对接流
 * @param is:输入流
 * @param os:输出流
 */
public static void copy2(InputStream is,OutputStream os) {
	//1.创建源
	//2.选择流
	try(is;os) {
		//3.操作
		byte[] flush = new byte[1024]; //缓冲容器
		int len; //接收长度
		while((len=is.read(flush))!=-1) {
			os.write(flush, 0, len);
		}
		os.flush();
	}catch(FileNotFoundException e) {
		e.printStackTrace();
	}catch(IOException e) {
		e.printStackTrace();
	}
}

哈哈,看上去是不是简洁很多。对的,随着JDK的新版本发布,越来越多的新技术,也使得代码看起来越简洁,不过对我们的要求也只会越来越高。前段时间JDK12已经出来了,还没用,不过我相信肯定会有好多的新特性,期待,也看好Java,加油。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值