通道(Channel)的原理获取

通道表示打开到 IO 设备(例如:文件、套接字)的连接。若需要使用 NIO 系统,需要获取用于连接 IO 设备的通道以及用于容纳数据的缓冲区。然后操作缓冲区,对数据进行处理。Channel 负责传输, Buffer 负责存储。通道是由 java.nio.channels 包定义的。 Channel 表示 IO 源与目标打开的连接。Channel 类似于传统的“流”。只不过 Channel本身不能直接访问数据, Channel 只能与Buffer 进行交互。

java.nio.channels.Channel 接口:

          |--FileChannel  本地文件的通道

          |--SocketChannel

          |--ServerSocketChannel

          |--DatagramChannel

网络的关于通道

获取通道

  1. Java 针对支持通道的类提供了 getChannel() 方法

          本地 IO:

          FileInputStream/FileOutputStream

          RandomAccessFile

 

          网络IO:

          Socket

          ServerSocket

          DatagramSocket

         

  2. 在 JDK 1.7 中的 NIO.2 针对各个通道提供了静态方法 open()

  3. 在 JDK 1.7 中的 NIO.2 的 Files 工具类的 newByteChannel()

package com.toov5.Nio;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import org.junit.jupiter.api.Test;


public class BUfferTest02 {
    // 非直接缓冲区 读写操作
    @Test
    public  void BUfferTest() throws IOException {
        // 读入流
        FileInputStream fileInputStream = new FileInputStream("aa.jpg");
        // 写入流
        FileOutputStream fileOutputStream = new FileOutputStream("bb.jpg");
        // 创建通道
        FileChannel iChannel = fileInputStream.getChannel(); // 读入流的通道
        FileChannel oChannel = fileOutputStream.getChannel(); // 写入流的通道
        //分配制定缓冲区大小
      ByteBuffer byteBuffer    = ByteBuffer.allocate(1024);
      while (iChannel.read(byteBuffer) != -1) {
            //开启读取模式
          byteBuffer.flip();
          //将数据写入到通道中
          oChannel.write(byteBuffer);
          byteBuffer.clear();          
    }
      //关闭通道、关闭连接
      iChannel.close();
      oChannel.close();
      fileInputStream.close();
      fileOutputStream.close();
      
    }
  
}

 

运行结果:

 

 直接缓冲区:

package com.toov5.Nio;

import java.io.FileInputStream;
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.jupiter.api.Test;


public class BUfferTest02 {
    @Test
    public void testZhiJie() throws IOException {
        //创建管道
    FileChannel inChannel =FileChannel.open(Paths.get("aa.jpg"), StandardOpenOption.READ);
    FileChannel outChannel =FileChannel.open(Paths.get("bb.jpg"),StandardOpenOption.READ,StandardOpenOption.WRITE,StandardOpenOption.CREATE );
    //定义映射文件
    MappedByteBuffer inMappedByteBuffer =inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
    MappedByteBuffer outMappedByteBuffer =outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());
    //直接对缓冲区操作
     byte[] bytes = new byte[inMappedByteBuffer.limit()];
     inMappedByteBuffer.get(bytes);
     outMappedByteBuffer.put(bytes);
      inChannel.close();
      outChannel.close();
      System.out.println("操作直接缓冲区完毕");
    }
    
    
    
    // 非直接缓冲区 读写操作
    @Test
    public  void BUfferTest() throws IOException {
        // 读入流
        FileInputStream fileInputStream = new FileInputStream("aa.jpg");
        // 写入流
        FileOutputStream fileOutputStream = new FileOutputStream("bb.jpg");
        // 创建通道
        FileChannel iChannel = fileInputStream.getChannel(); // 读入流的通道
        FileChannel oChannel = fileOutputStream.getChannel(); // 写入流的通道
        //分配制定缓冲区大小
      ByteBuffer byteBuffer    = ByteBuffer.allocate(1024);
      while (iChannel.read(byteBuffer) != -1) {
            //开启读取模式
          byteBuffer.flip();
          //将数据写入到通道中
          oChannel.write(byteBuffer);
          byteBuffer.clear();          
    }
      //关闭通道、关闭连接
      iChannel.close();
      oChannel.close();
      fileInputStream.close();
      fileOutputStream.close();
      
    }
  
}

 

 

posted @ 2018-11-08 22:59  toov5  阅读(739)  评论(0编辑  收藏  举报