NIO入门02

本文详细介绍了Java NIO(非阻塞I/O)的使用方法,包括通道(Channel)的概念及其在数据传输中的作用,如何通过FileChannel进行文件复制,并探讨了直接缓冲区与内存映射文件在文件复制过程中的应用。通过对比不同复制方式的效率,展示了内存映射文件在处理大数据量时的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package com.sico.pck01_nio;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

import org.junit.Test;

/**
*

  • @author Administrator
  • 1、通道:主要用于目标节点与源节点的连接,用于数据的传输,但是需要与缓冲区配合使用。(独立的处理器,管理io,提高cpu的利用率)
  • 2、主要用到的通道:
  • java.nio.channels.Channel:
  •   |--FileChannel
    
  •   |--SocketChannel
    
  •   |--ServerSocketChannel
    
  •   |--DatagramChannel
    
  • 3、获取通道的方法如下:
  • (1)getChannel;(Local IO:)FileInputStream/FileOutputStream/RandomAccessFile和(Net IO:)Socket/ServerSocket/DatagramSocket拥有此方法。
  • (2)JDK1.7的nio2中的static open();
  • (3)JDK1.7的nio中的工具类Files static newByteChannel(path, options)
  • 4、通道之间的数据传输:
  •  |--(1)transforFrom
    
  •  |--(2)transforTo
    

*/
public class Nio02 {

/**
 * 通过通道进行文件的复制
 */
@Test
public void fun01(){
	  try {
		//1、创建输入、输出流
		FileInputStream is = new FileInputStream("./img/1.jpg");
		FileOutputStream os = new FileOutputStream("./img/2.jpg");
		
		//2、根据流获取通道
		FileChannel fic = is.getChannel();
		FileChannel foc = os.getChannel();
		
		//3、创建缓冲区
		ByteBuffer buf = ByteBuffer.allocateDirect(1024);
		
		//4、完成文件的复制
		//通过通道读取文件到缓冲区
		try {
			while((fic.read(buf))!=-1){
				buf.flip();//切换模式
				//缓冲区的内容写到通道
				foc.write(buf);
				buf.clear();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(fic!=null){
				try {
					fic.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(foc!=null){
				try {
					foc.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(is!=null){
				try {
					is.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(os!=null){
				try {
					os.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	}
}

/**
 * 通过直接缓冲区完成文件的复制(内存映射文件),注意只有ByteBuffer支持
 * @throws IOException 
 */
@Test
public void fun02() throws IOException{
	
	long startTime = System.currentTimeMillis();
	//1、获取通道
	FileChannel inChannel = FileChannel.open(Paths.get("./img/1.jpg"),StandardOpenOption.READ);
	FileChannel outChannel = FileChannel.open(Paths.get("./img/3.jpg"), StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE);
	
	//2、获取缓冲区,内存映射文件,现在的 缓冲区在物理内存中
	MappedByteBuffer inMapBuf = inChannel.map(MapMode.READ_ONLY,0, inChannel.size());
	MappedByteBuffer outMapBuf = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());
	
	//3、直接缓冲区进行读写
	byte[] dst=new byte[inMapBuf.limit()];
	inMapBuf.get(dst);
	outMapBuf.put(dst);
	
	inChannel.close();
	outChannel.close();
	long endTime=System.currentTimeMillis();
	System.out.println("文件的复制所花费时间:"+(endTime-startTime));
	
}

/**
 * 直接缓冲区(物理內存)
 * @throws IOException
 */
@Test
public void fun03() throws IOException{
	

	FileChannel inChannel = FileChannel.open(Paths.get("./img/1.jpg"),StandardOpenOption.READ);
	FileChannel outChannel = FileChannel.open(Paths.get("./img/5.jpg"), StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE);

// inChannel.transferTo(0, inChannel.size(), outChannel);
outChannel.transferFrom(inChannel, 0, inChannel.size());

	inChannel.close();
	outChannel.close();
	
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值