3.6 Introduction to Channels

Channels: defined by java.nio.Channels Channel indicates the open connection between the I/O source and the destination. A Channel is similar to a traditional stream. However, the Channel itself cannot access the data directly; it can only interact with buffers

3.7 Channel Model

3.8 Channel implementation classes

  • FileChannel: Channel for reading, writing, mapping, and manipulating files.

  • DatagramChannel: Reads and writes data channels on the network through UDP.

  • SocketChannel: Reads and writes data on the network through TCP.

  • ServerSocketChannel: Listens for incoming TCP connections and creates a SocketChannel for each incoming connection

3.8.1 Obtaining channels

One way to get channels is to call the getChannel() method on objects that support channels. The following classes support channels:

  • FileInputStream

  • FileOutputStream

  • RandomAccessFile

  • DatagramSocket

  • Socket

  • ServerSocket

Another way to get a channel is to get a byte channel using the static method newByteChannel() of the Files class. Or the static method open() for the channel opens and returns the specified channel.

3.8.2 Data transmission over channels

  • Write Buffer data to Channel

  • Read data from Channel to Buffer

1. Copy files using channels (indirect buffer)

 	/** * Copy files using channels (non-direct buffers) */
    @Test
    public void test01(a) {
        FileInputStream fis = null;
        FileOutputStream fos = null;

        //1. Obtain the channel
        FileChannel inChannel = null;
        FileChannel outChannel = null;
        try {
            fis = new FileInputStream("d:/1.mp4");
            fos = new FileOutputStream("d:/2.mp4");

            inChannel = fis.getChannel();
            outChannel = fos.getChannel();

            //2. Allocate a buffer of the specified size
            ByteBuffer buf = ByteBuffer.allocate(1024);

            //3. Store channel data in a buffer
            while(inChannel.read(buf) ! = -1) {
                // Switch the data read mode
                buf.flip();
                //4. Write buffer data to channeloutChannel.write(buf); buf.clear(); }}catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(fis ! =null) {
                try {
                    fis.close();
                } catch(IOException e) { e.printStackTrace(); }; }if(fos ! =null) {
                try {
                    fos.close();
                } catch(IOException e) { e.printStackTrace(); }; }if(inChannel ! =null) {
                try {
                    inChannel.close();
                } catch(IOException e) { e.printStackTrace(); }; }if(outChannel ! =null) {
                try {
                    outChannel.close();
                } catch(IOException e) { e.printStackTrace(); }; }}}Copy the code

2. Use the direct buffer to copy files (memory-mapped files) ps: not recommended

    /** * Use the direct buffer to complete the file copy (memory mapped file) */
    @Test
    public void test02(a) {
        //1. Obtain the channel
        FileChannel inChannel = null;
        FileChannel outChannel = null;
        
        //2. Memory mapped file
        MappedByteBuffer inMapperBuf = null;
        MappedByteBuffer outMapperBuf = null;
        
        try {
            inChannel = FileChannel.open(Paths.get("d:/1.mp4"), 
                    / / read
                    StandardOpenOption.READ);
            
            outChannel = FileChannel.open(Paths.get("d:/3.mp4"), 
                    / / read
                    StandardOpenOption.READ, 
                    / / create
                    StandardOpenOption.CREATE_NEW, 
                    / / write
                    StandardOpenOption.WRITE);
            // Write data directly to the buffer
            byte[] dst = new byte[inMapperBuf.limit()];
            inMapperBuf.get(dst);
            outMapperBuf.put(dst);
            
        } 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(); }}}}Copy the code

3. Data transfer between channels (direct buffer) transferFrom/transferTo

    /** * Data transfer between channels (direct buffer) */
    @Test
    public void test03(a) {
        //1. Obtain the channel
        FileChannel inChannel = null;
        FileChannel outChannel = null;

        try {
            inChannel = FileChannel.open(Paths.get("d:/1.mp4"));
            outChannel = FileChannel.open(Paths.get("d:/4.mp4"),
                    StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);
            // Choose one or the other, pay attention to the API
// inChannel.transferTo(0, inChannel.size(), outChannel);
            outChannel.transferFrom(inChannel, 0, inChannel.size());
        } 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(); }}}}Copy the code