使用java进行文件复制

     文件复制的过程很简单,从源文件读出数据,再写到目标文件就实现了文件复制,java强大的I/O实现起来很简单,下面是一个文件copy方法:

    public static void copy2(String src, String dest) {
        int readBufferSize = 4096;
        File from_file = new File(src);
        File to_file = new File(dest);

        FileInputStream from = null;  // Stream to read from source
        FileOutputStream to = null;   // Stream to write to destination
        try {
            from = new FileInputStream(from_file);  
            to = new FileOutputStream(to_file);     
            byte[] buffer = new byte[readBufferSize];
            int bytes_read;                         
           
            while((bytes_read = from.read(buffer)) != -1) 
                to.write(buffer,0,bytes_read);          
        }
        finally {
            if (from != null)
            	try {
            		from.close(); 
            	}catch(IOException e){
            		from = null;
            		e.printStackTrace();
            	}
            if (to != null)
            	try {
            		to.close();
            	} catch (IOException e){
            		to = null;
            		e.printStackTrace();
            	}
        }
    }

 

下面改进一下,用带缓冲的输入输出流:

    public static void copy2(String src, String dest) {
		int readBufferSize = 4096;
		File from_file = new File(src);
		File to_file = new File(dest);

		BufferedInputStream bisFrom = null; // Stream to read from source
		BufferedOutputStream bisTo = null; // Stream to write to destination
		try {
			bisFrom = new BufferedInputStream(new FileInputStream(from_file));
			bisTo = new BufferedOutputStream(new FileOutputStream(to_file));
			byte[] buffer = new byte[readBufferSize]; // byte buffer
			int bytes_read;

			while ((bytes_read = bisFrom.read(buffer)) != -1)
				bisTo.write(buffer, 0, bytes_read);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (bisFrom != null)
					bisFrom.close();
				if (bisTo != null)
					bisTo.close();
			} catch (IOException e) {
				bisFrom = null;
				bisTo = null;
			}
		}
	}

 除了使用java传统的I/O 外,使用nio包里FileChannel类也可以很方便的实现文件复制,下面是一个使用FileChannel的方法:

    public static void copyFile(String src, String dest) {
		File srcFile = new File(src);
		File destFile = new File(dest);
		FileChannel sourceChannel = null;
		FileChannel destinationChannel = null;

		try {
			sourceChannel = new FileInputStream(srcFile).getChannel();
			destinationChannel = new FileOutputStream(destFile).getChannel();
			sourceChannel.transferTo(0, sourceChannel.size(),destinationChannel);
			// or
			// destinationChannel.transferFrom(sourceChannel,0,sourceChannel.size());
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (sourceChannel != null)
					sourceChannel.close();
				if (destinationChannel != null)
					destinationChannel.close();
			} catch (IOException e) {
				sourceChannel = null;
				destinationChannel = null;
			}
		}

	}
    

 使用FileChannel果然简单,一个方法就ok了,那么上面三种方法实现的文件复制速度一样快吗?如果不一样,哪种方式的效率更高一些呢?一般会认为nio具有更高的效率,那FileChannel会不会更快一些呢?实践一下便知。

目标文件选用一个689M大的iso文件,从一个磁盘分区复制到另外一个分区

系统环境: cpu:E2160,内存:单条2G,操作系统:windows xp sp2,JDK1.6.10

测试结果:

方法1 耗时33204毫秒,方法2 耗时23781毫秒,方法3 耗时53859毫秒

实测的结果是FileChannel最慢,而且竟然比文件流读写方式慢了一倍!

是不是一次传输整个文件影响效率呢,看看分段循环传输会不会好一些,把方法3改成下面的形式:

    public static void copyFile2(String src, String dest) {
		File srcFile = new File(src);
		File destFile = new File(dest);
		FileChannel sourceChannel = null;
		FileChannel destinationChannel = null;
		long buffer = 4096;
		long byteWritten = 0;

		try {
			sourceChannel = new FileInputStream(srcFile).getChannel();
			destinationChannel = new FileOutputStream(destFile).getChannel();
			long filesize = sourceChannel.size();
			while (byteWritten < filesize) {
				long written = sourceChannel.transferTo(byteWritten, buffer,destinationChannel);
				byteWritten += written;
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				sourceChannel.close();
				destinationChannel.close();
			} catch (IOException e) {
				sourceChannel = null;
				destinationChannel = null;
			}
		}
	}

 再做测试,成绩为:31344毫秒 ,果然比一次传输的方式快了不少,速度基本和文件流读写方式持平。

 

从实际测试结果可以看出,对于比较大的文件,FileChannel循环传输的方式比一次传输速度快,和FileInputStream/FileOutputStream的速度相当,而带缓冲的流读写速度最快。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值