Java_IO_两种文件复制方式比较

12 篇文章 2 订阅
本文对比了Java中两种文件复制的方法:使用缓冲输入输出流(InputStream、OutputStream)和文件通道(FileChannel),详细阐述了各自的操作过程和特点。
摘要由CSDN通过智能技术生成

一:缓冲输入输出流(InputStream、OutputStream)

<span style="font-size:14px;">	/*
	 *缓冲输入输出流方式复制文件 
	 */
	public static boolean copyFile(String srcFileName,String destFileName,boolean overlay){
			File srcFile = new File(srcFileName); //根据一个路径得到File对象
			//判断源文件是否存在
			if(!srcFile.exists()){
				try{
					throw new Exception("源文件:"+srcFileName+"不存在!");
				}catch(Exception e){
					e.printStackTrace();//将异常内容存到日志文件中
				}
				return false;
			}else if(!srcFile.isFile()){//判断是不是一个文件
				try {
					throw new Exception("复制文件失败,源文件:"+srcFileName+"不是一个文件!");
				} catch (Exception e) {
				
					e.printStackTrace();
				}
				return false;
				
			}
			//判断目标文件是否存在
			File destFile = new File(destFileName);//目标文件对象destFile
			if(destFile.exists()){
				//如果目标文件存在并允许覆盖
				if(overlay){
					//删除已经存在的目标文件
					new File(destFileName).delete();
					
				}
			}else{
				//如果目标文件所在目录不存在,则创建 目录
				if(!destFile.getParentFile().exists()){
					//目标文件所在目录不存在
					//mkdirs():创建此抽象路径名指定的目录,包括所有必需但不存在的父目录
					if(!destFile.getParentFile().mkdirs()){
						//复制文件失败:创建目标文件所在目录失败
						return false;
					}
				}
			}
			
			//复制文件
			int byteread = 0;//读取的字节数
			InputStream  in = null;
			OutputStream  out = null;
			
			try {
				in  = new FileInputStream(srcFile);
				out = new FileOutputStream(destFile);
				byte[] buffer = new byte[1024];
				/*
				 * 方法说明:
				 * ①:将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
				 * 		write(byte[] b, int off, int len) 
				 * 			b - 数据
				 * 			off - 数据中的起始偏移量。
				 * 			len - 要写入的字节数。 
				 * ②:in.read(buffer))!=-1,是从流buffer中读取一个字节,当流结束的时候read返回-1
				 */

				while((byteread = in.read(buffer))!=-1){
					out.write(buffer, 0, byteread);
				}
				return true;
			} catch (FileNotFoundException e) {
				
				return false;
			} catch (IOException e) {
				return false;
			}finally{
				try {
					if(out!=null){
						out.close();
					}
					if(in!=null){
						in.close();
					}
				} catch (IOException e) {
					
					e.printStackTrace();
				}
			}
	}</span>

二:文件通道(FileChannel)

<span style="font-size:14px;">	/*
	 * 使用文件通道的方式复制文件
	 */
	public static void fileChannelCopy(String srcDirName,String destDirName){
		FileInputStream fi = null;
		FileOutputStream fo = null;
		FileChannel in = null;
		FileChannel out = null;
		
		try {
			fi = new FileInputStream(new File(srcDirName));
			fo = new FileOutputStream( new File(destDirName));
			in = fi.getChannel();//得到对应的文件通道
			out = fo.getChannel();//得到对应的文件通道
			/*
			 * 		 public abstract long transferTo(long position, long count,
             		                     WritableByteChannel target)throws IOException;
			 * 			position - 文件中的位置,从此位置开始传输;必须为非负数  
			 * 			count - 要传输的最大字节数;必须为非负数  
			 * 			target - 目标通道   
			 *			返回:  
						实际已传输的字节数,可能为零  
			 */
			in.transferTo(0, in.size(), out);//连接两个通道,并且从in通道读取,然后写入out通道中
		} catch (FileNotFoundException e) {
		
			e.printStackTrace();
		} catch (IOException e) {
		
			e.printStackTrace();
		}finally{
			try {
				fi.close();
				in.close();
				fo.close();
				out.close();
			} catch (IOException e) {
				
				e.printStackTrace();
			}
		}
		
	}</span>
测试上面的两个方法:
<span style="font-size:14px;">public class copyFile{
	public static void main(String[] args) {
		String srcDirName = "E:/360cse_official.exe";//待复制的文件名
		String destDirName ="E:/360cse_official_test.exe";//目标文件名
		long start;
		long end;
		start = System.currentTimeMillis();//返回系统的当前时间
		copyFile.copyFile(srcDirName,destDirName,true);
		end = System.currentTimeMillis();
		System.out.println("缓冲输入输出流方式复制文件,用时:"+(end-start)+"ms");
		
		start = System.currentTimeMillis();
		copyFile.fileChannelCopy(srcDirName,destDirName);
		end = System.currentTimeMillis();
		System.out.println("使用文件通道的方式复制文件,用时:"+(end-start)+"ms");
		
	}</span>
测试文件:

运行结果:
缓冲输入输出流方式复制文件,用时:499ms
使用文件通道的方式复制文件,用时:57ms

总结:

通过对上面两个方法测试,我们可以知道使用文件通道的方式复制文件,明显比输出流复制文件效率要高。
学到的知识点:
①:返回系统的当前时间:start = System.currentTimeMillis();
②:write(byte[] b, int off, int len) 方法
将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流
b - 数据
off - 数据中的起始偏移量。
len - 要写入的字节数。 
③:in.read(buffer))!=-1,是从流buffer中读取一个字节,当流结束的时候read返回-1
④:in.transferTo(0, in.size(), out);//连接两个通道,并且从in通道读取,然后写入out通道中

public abstract long transferTo(long position, long count,
            WritableByteChannel target)throws IOException;
position - 文件中的位置,从此位置开始传输;必须为非负数  
count - 要传输的最大字节数;必须为非负数  
target - 目标通道   
返回:  
实际已传输的字节数,可能为零  
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值