Java-NIO-Channel-笔记

一、通道(Channel):用于源节点与目标节点的连接。
 *   在Java-NIO中负责缓冲区数据的传输。Channel本身不存储数据,需要配合缓冲区进行传输。
 * 二、通道的主要实现类
 *   java.nio.channels.channel 接口:
 *       |---FileChannel
 *       |---SocketChannel
 *       |---ServerSocketChannel
 *       |---DatagramChannel
 * 三、获取通道
 *   1.Java针对支持通道的实现类提供了getChannel()方法
 *     本地IO
 *       FileInputStream/FileOutputStream   
 *       RandomAccessFile
 *     网络IO
 *       Socket
 *       ServerSocket
 *       DatagramSocket
 *   2.在JDK1.7中的NIO.2 针对各个通道提供了静态方法open()
 *   3.在JDK1.7中的NIO.2 的Files工具类  newByteChannel()
 *     
 * 四、通道之间的数据传输
 *   transferFrom()
 *   transferTo()
 *
 * 五、分散(Scatter)与聚集(Gather)
 *    分散读取(Scattering Reads):将通道中的数据分散到多个缓冲区中
 *    聚集写入(Gathering Writes):将多个缓冲区中的数据聚集到通道中
 *
 * 六、字符集  : Charset
 *    编码:字符串 -> 字节数组  (将看的懂的转为看不懂的为编码)

 *    解码:字节数组  -> 字符串 (将看不懂的转为看的懂的为解码)

 //利用通道完成文件的复制(非直接缓冲区)
	@Test
	public void test1() throws IOException{
		FileInputStream fileInputStream = new FileInputStream("Java.pdf");
	        FileOutputStream fileOutputStream = new FileOutputStream("JavaCopy.pdf");
		
		FileChannel inChannel =	fileInputStream.getChannel();
		FileChannel outChannel = fileOutputStream.getChannel();
		
		ByteBuffer buf = ByteBuffer.allocate(1024); //分配一个直接缓冲区
		
		while((inChannel.read(buf))!=-1){
			buf.flip(); //切换到读取数据模式
			outChannel.write(buf);
			buf.clear();
		}
		outChannel.close();
		inChannel.close();
		fileOutputStream.close();
		fileInputStream.close();
	}
	
	//使用直接缓冲区完成文件的复制
	@Test
	public void test2() throws IOException{
		
	   //建立通道
	   FileChannel incChannel = FileChannel.open(Paths.get("Java.pdf"),StandardOpenOption.READ);
           FileChannel outChannel = FileChannel.open(Paths.get("JavaCopy.pdf"),StandardOpenOption.WRITE,
                                                                    StandardOpenOption.READ,StandardOpenOption.CREATE);					
		
	   //内存映射文件
           MappedByteBuffer inMappedByteBuffer = incChannel.map(FileChannel.MapMode.READ_ONLY,0,incChannel.size());
           MappedByteBuffer outMappedByteBuffer = outChannel.map(FileChannel.MapMode.READ_WRITE,0,incChannel.size());
		
           //直接对缓冲区进行数据的读写操作
           byte[] dst = new byte[inMappedByteBuffer.limit()];
           inMappedByteBuffer.get(dst);
           outMappedByteBuffer.put(dst);
        
           outChannel.close();
           incChannel.close();
	}
	
	//通道之间的传输(直接缓冲区)
	@Test
	public void test3() throws IOException{
		
	    //建立通道
	    FileChannel inChannel =	FileChannel.open(Paths.get("Java.pdf"),StandardOpenOption.READ);
	    FileChannel outChannel = FileChannel.open(Paths.get("JavaCopy.pdf"),StandardOpenOption.READ,
                                                            StandardOpenOption.WRITE,StandardOpenOption.CREATE);
		
	     inChannel.transferTo(0,inChannel.size(),outChannel);
	    //outChannel.transferFrom(inChannel,0,inChannel.size());
	    
	    outChannel.close();
	    inChannel.close();
	}
	
	//分散与聚集
	@Test
	public void test4() throws IOException{
		
		RandomAccessFile rsf1 = new RandomAccessFile("Java.pdf","rw");
		
		//1.获取通道
		FileChannel channel1 = rsf1.getChannel();
		
		//2.分配指定大小的缓冲区
		ByteBuffer buf1 = ByteBuffer.allocate(100);
		ByteBuffer buf2 = ByteBuffer.allocate(1024);
		
		//3.分散读取
		ByteBuffer[] dsts = {buf1,buf2};
		channel1.read(dsts);
		
		for (ByteBuffer byteBuffer : dsts) {
			byteBuffer.flip();
		}
		
		System.out.println(new String(dsts[0].array(),0,dsts[0].limit()));
		System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
		System.out.println(new String(dsts[1].array(),0,dsts[1].limit()));
		
		RandomAccessFile rsf2 = new RandomAccessFile("JavaCopy.pdf","rw");
		FileChannel channel2 = rsf2.getChannel();
		channel2.write(dsts);
	}
	
	//获取编码集
	@Test
	public void test5(){
		SortedMap<String,Charset> sdm = Charset.availableCharsets();
		
		Set<Entry<String,Charset>> set = sdm.entrySet();
		
		for (Entry<String, Charset> entry : set) {
			System.out.println(entry.getKey()+"~~~"+entry.getValue());
		}
	}
	
	//字符集
	@Test
	public void test6() throws CharacterCodingException{
		
	    Charset cs1 = Charset.forName("GBK");
	   
	    CharsetEncoder ce = cs1.newEncoder();  //获取编码器
	    
	    CharsetDecoder cd = cs1.newDecoder(); //获取解码器
	    
	    CharBuffer cbuf = CharBuffer.allocate(1024);
	    cbuf.put("测试编码");
	    cbuf.flip();
	    
	    ByteBuffer buffer = ce.encode(cbuf);
	    
	    //解码
	    CharBuffer cBuf2 = cd.decode(buffer);
		System.out.println(cBuf2.toString());
	}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值