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

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

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

@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秒app

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

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

@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秒code

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

使用直接缓冲区完成文件的复制(内存映射文件)耗时为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秒ci

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

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