NIO复制文件的三种方式对比

下面对NIO复制文件的三种方式进行对比:

方式一:利用通道完成文件的复制(非直接缓冲区)

@Test
public void copyFirst(){
		
		// 为了比较效率,记录程序执行时间
		long startTime = System.currentTimeMillis();  // 开始时间
		
		// 1 声明输入输出流
		FileInputStream fis = null;
		FileOutputStream fos = null;
		// 2 声明通道
		FileChannel inChannel = null;
		FileChannel outChannel = null;
		
		try {
			// 3 创建输入输出流
			fis = new FileInputStream("C:/Java/NIO.pdf");
			fos = new FileOutputStream("C:/Java/newNIO.pdf");
			
			// 4 获取通道
			inChannel = fis.getChannel();
			outChannel = fos.getChannel();
			
			// 5 分配指定大小的缓冲区
			ByteBuffer buffer = ByteBuffer.allocate(1024);
			
			// 6 将通道中的数据存入缓存区中
			while(inChannel.read(buffer) != -1){
				buffer.flip();  // 切换到读取数据的模式
				// 7 将缓存区中的数据写入通道中
				outChannel.write(buffer);
				buffer.clear();  // 清空缓存区
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(outChannel != null){
				try{
					outChannel.close();
				}catch(IOException e){
					e.printStackTrace();
				}
			}
			if(inChannel != null){
				try{
					inChannel.close();
				}catch(IOException e){
					e.printStackTrace();
				}
			}
			if(fos != null){
				try{
					fos.close();
				}catch(IOException e){
					e.printStackTrace();
				}
			}
			if(fis != null){
				try{
					fis.close();
				}catch(IOException e){
					e.printStackTrace();
				}
			}
		}
		
		// 记录结束时间
		long endTime = System.currentTimeMillis();
		System.out.println("用通道完成文件的复制(非直接缓冲区)耗时为" + (endTime - startTime) + "秒");
	}
	

运行三次的时间分别为:

用通道完成文件的复制(非直接缓冲区)耗时为1220秒

用通道完成文件的复制(非直接缓冲区)耗时为1213秒

用通道完成文件的复制(非直接缓冲区)耗时为1226秒

第二种方法:使用直接缓冲区完成文件的复制(内存映射文件)

@Test
public void copySecond(){
		
		long startTime = System.currentTimeMillis();
		
		FileChannel inChannel = null;
		FileChannel outChannel = null;		
		
		try {
			// 获取通道
			inChannel = FileChannel.open(Paths.get("C:/Java/NIO.pdf"), StandardOpenOption.READ);
			outChannel = FileChannel.open(Paths.get("C:/Java/newNIO.pdf"), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
			
			// 设置内存映射文件
			MappedByteBuffer imb = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
			MappedByteBuffer omb = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());
			
			// 直接对缓冲区进行数据的读写操作
			byte[] data = new byte[imb.limit()];
			imb.get(data);
			omb.put(data);
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(inChannel != null){
				try {
					inChannel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(outChannel != null){
				try {
					outChannel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		// 记录结束时间
		long endTime = System.currentTimeMillis();
		System.out.println("使用直接缓冲区完成文件的复制(内存映射文件)耗时为" + (endTime - startTime) + "秒");
	}

运行三次的时间分别为:

使用直接缓冲区完成文件的复制(内存映射文件)耗时为107秒

使用直接缓冲区完成文件的复制(内存映射文件)耗时为112秒

使用直接缓冲区完成文件的复制(内存映射文件)耗时为107秒

方式三:通道之间的数据传输(直接缓存区) 

@Test
public void copyThird(){
		
		long startTime = System.currentTimeMillis();
		
		FileChannel inChannel = null;
		FileChannel outChannel = null;
		
		try {
			inChannel = FileChannel.open(Paths.get("C:/Java/NIO.pdf"), StandardOpenOption.READ);
			outChannel = FileChannel.open(Paths.get("C:/Java/newNIO.pdf"), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
			inChannel.transferTo(0, inChannel.size(), outChannel);
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(inChannel != null){
				try {
					inChannel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(outChannel != null){
				try {
					outChannel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		long endTime = System.currentTimeMillis();
		System.out.println("通道之间的数据传输(直接缓存区)耗时为" + (endTime - startTime) + "秒");
	}

运行三次的时间分别为:

通道之间的数据传输(直接缓存区)耗时为73秒

通道之间的数据传输(直接缓存区)耗时为64秒

通道之间的数据传输(直接缓存区)耗时为68秒

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是Java复制文件的四种方式,分别使用FileInputStream和BufferedInputStream类中的两种read()方法: 方式一:使用FileInputStream的read()方法逐字节复制文件 ```java import java.io.*; public class FileCopyDemo1 { public static void main(String[] args) throws IOException { long start = System.currentTimeMillis(); FileInputStream fis = new FileInputStream("d:\\bbb.mp4"); FileOutputStream fos = new FileOutputStream("copy.mp4"); int b; while ((b = fis.read()) != -1) { fos.write(b); } fis.close(); fos.close(); long end = System.currentTimeMillis(); System.out.println("用时:" + (end - start) + "毫秒"); } } ``` 方式二:使用FileInputStream和BufferedInputStream的read()方法读取缓冲区,每次复制1024字节 ```java import java.io.*; public class FileCopyDemo2 { public static void main(String[] args) throws IOException { long start = System.currentTimeMillis(); FileInputStream fis = new FileInputStream("d:\\bbb.mp4"); BufferedInputStream bis = new BufferedInputStream(fis); FileOutputStream fos = new FileOutputStream("copy.mp4"); byte[] buffer = new byte[1024]; int len; while ((len = bis.read(buffer)) != -1) { fos.write(buffer, 0, len); } bis.close(); fis.close(); fos.close(); long end = System.currentTimeMillis(); System.out.println("用时:" + (end - start) + "毫秒"); } } ``` 方式三:使用FileInputStream和BufferedInputStream的read()方法读取缓冲区,每次复制8192字节 ```java import java.io.*; public class FileCopyDemo3 { public static void main(String[] args) throws IOException { long start = System.currentTimeMillis(); FileInputStream fis = new FileInputStream("d:\\bbb.mp4"); BufferedInputStream bis = new BufferedInputStream(fis); FileOutputStream fos = new FileOutputStream("copy.mp4"); byte[] buffer = new byte[8192]; int len; while ((len = bis.read(buffer)) != -1) { fos.write(buffer, 0, len); } bis.close(); fis.close(); fos.close(); long end = System.currentTimeMillis(); System.out.println("用时:" + (end - start) + "毫秒"); } } ``` 方式四:使用Files.copy()方法复制文件 ```java import java.io.*; import java.nio.file.*; public class FileCopyDemo4 { public static void main(String[] args) throws IOException { long start = System.currentTimeMillis(); Path source = Paths.get("d:\\bbb.mp4"); Path target = Paths.get("copy.mp4"); Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); long end = System.currentTimeMillis(); System.out.println("用时:" + (end - start) + "毫秒"); } } ``` 这里使用Java 8中的Files.copy()方法,可以一行代码完成文件复制操作。 经过测试,第一个方式复制文件最慢,第四个方式复制文件最快。第二和第三个方式的效率相差不大,但是第三个方式复制的字节数更多,因此第三个方式更高效。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值