Java nio basics 1:channel and buffer

Blocking IO

Read and write are blocked, and each request is a thread

non-blocking IO

Based on the Reactor working mode, IO is not blocked. Specific IO events are registered and the system will notify when specific events occur. The core object is the Selector,
When reading, writing and registration occur, the selector can find the Selector Channel where the event occurs and obtain the client data.

The non blocking IO event itself is not blocked, but the select() method to get the event is blocked. The essence is when IO occurs, rather than waiting as long as the IO stream is opened.

NIO

Core component: Channels Buffers Selectors

filechannel

Write file small example

public class io1 {
    public static void main(String[] args) throws IOException {
        File f = new File("C:\\Users\\86158\\Desktop\\datax.txt");
        RandomAccessFile ra = new RandomAccessFile(f,"rw");
        FileChannel fc = ra.getChannel();

        //Create buffer
        ByteBuffer bf = ByteBuffer.allocate(1024);

        String input = "abcdefg";

        bf.clear();
        bf.put(input.getBytes());
        bf.flip();

        while (bf.hasRemaining()){
            fc.write(bf);
        }
        fc.close();
    }
}

FileChannel
position is read and written in some specific location
Size returns the file size
truncate intercepted bytes
Force force write
Data transfer between transferTo/transferFrom channels

Small example of data transmission between channels

public class io2 {
    public static void main(String[] args) throws IOException {
        File f = new File("C:\\Users\\86158\\Desktop\\datax.txt");
        File f2 = new File("C:\\Users\\86158\\Desktop\\datax2.txt");
        RandomAccessFile ra1 = new RandomAccessFile(f,"rw");
        RandomAccessFile ra2 = new RandomAccessFile(f2,"rw");
        FileChannel fc1 = ra1.getChannel();
        FileChannel fc2 = ra1.getChannel();

        //fc1 data transfer in fc2
        fc1.transferTo(0,fc1.size(),fc2);

    }
}


socketChannel

serverSocketChannel can listen to the channel of new TCP connections

Listen to 8888 port

public class io3 {
    public static void main(String[] args) throws IOException, InterruptedException {
        int port = 8888;
        ByteBuffer bf = ByteBuffer.wrap("hello".getBytes());

        ServerSocketChannel ssc = ServerSocketChannel.open();
        ssc.socket().bind(new InetSocketAddress(port));

        //Set non blocking
        ssc.configureBlocking(false);

        //Listen for incoming new links
        while (true){
            SocketChannel sc = ssc.accept();
            if(sc == null){
                Thread.sleep(2000);
            }else {
                System.out.println(sc.socket().getRemoteSocketAddress());
                bf.rewind();
                sc.write(bf);
                sc.close();
            }

        }
    }
}

socketChannel
TCP oriented

public class io4 {
    public static void main(String[] args) throws IOException {
        SocketChannel sc = SocketChannel.open(new InetSocketAddress("www.baidu.com",80));

        sc.configureBlocking(false);
        ByteBuffer bf = ByteBuffer.allocate(100);
        sc.read(bf);
        sc.close();
        System.out.println("over");


    }
}

datagramChannel
UDP oriented

public class io5 {

    public  void send() throws IOException, InterruptedException {
        DatagramChannel dc = DatagramChannel.open();
        InetSocketAddress ad = new InetSocketAddress("127.0.0.1",9999);
        while (true){
            ByteBuffer bf = ByteBuffer.wrap("jsjsjsj".getBytes());
            dc.send(bf,ad);
            System.out.println("send out");
            Thread.sleep(1000);
        }

    }

    public void receive() throws IOException {
        DatagramChannel dc = DatagramChannel.open();
        InetSocketAddress ad = new InetSocketAddress(9999);
        dc.bind(ad);
        ByteBuffer bf = ByteBuffer.allocate(1024);
        while (true){
            bf.clear();
            SocketAddress sc = dc.receive(bf);
            bf.flip();

            System.out.println(sc.toString() + bf);
        }



    }
}

scatter and gather functions of channel

Buffer

It is a memory space that can be read and written. All data in NIO is processed by buffer

There are two methods to allocate buffers:
ByteBuffer buf = ByteBuffer.allocate(10);
Opened in the heap, easy to manage, garbage collector can be recycled, space is limited, reading and writing is slow.

ByteBuffer buf2=ByteBuffer.allocateDirect(10);
The physical memory opens up space, which is relatively large, and the speed of reading and writing files is fast, which is not controlled by the garbage collector.

buffer read / write operation

public class io6 {
    public static void main(String[] args) throws IOException {
        buffer01();
    }

    public static void buffer01() throws IOException {
        RandomAccessFile ra = new RandomAccessFile("C:\\Users\\86158\\Desktop\\datax.txt","rw");
        FileChannel channel = ra.getChannel();
        ByteBuffer bf = ByteBuffer.allocate(1024);

        //read
        channel.read(bf);
        bf.flip();
        while (bf.hasRemaining()){
            System.out.println((char) bf.get());
        }
        bf.clear();


        //write
        for (int ii = 0; ii < bf.capacity();ii++){
            bf.put((byte) ii);
        }
        bf.flip();
        while (bf.hasRemaining()){
            System.out.println((char) bf.get());
        }
        bf.clear();

    }
}

buffer attribute capacity position limit

capacity: how much can I write at most

Position: the current position of reading and writing. It changes to 0 after flip

limit: where to read most (position before flip) / where to write most (capacity)

There are two ways to put data into the buffer

buffer.put()
channel.read(buffer)

buffer read data
buffer.get()
channel.write(buffer)

rewind method / flip method

flip is written and read. The limit should be set to position, and position becomes 0

rewind is a simple position that becomes 0

clear method / compact method

clear: position is set to 0
compact: ready to write data, unread data will not be cleared, unread data will be copied to the beginning of buffer, and position will be set after the last unread data

mark method / reset method

mark marks a specific position, and reset restores to this position

buffer fragmentation

In NIO, in addition to allocating or wrapping a buffer object, it can also be based on the existing buffer object
To create a sub buffer, that is, cut out a piece of the existing buffer as a new buffer, but the existing buffer
The buffer and the created sub buffer share data at the underlying array level, that is, the sub buffer is equivalent
A view window of the existing buffer. Call the slice() method to create a sub buffer.

The slice range is the data from the position of the original buffer to the limit index when the slice method is called

buffer read only

Read only buffers are very simple. You can read them, but you can't write data to them. You can call the buffer
The asReadOnlyBuffer() method of the buffer converts any conventional buffer into a read-only buffer. This method returns
Returns a buffer that is exactly the same as the original buffer and shares data with the original buffer, but it is read-only.
If the contents of the original buffer change, the contents of the read-only buffer also change

Area equivalent
A view window of the existing buffer. Call the slice() method to create a sub buffer.

The slice range is the data from the position of the original buffer to the limit index when the slice method is called

buffer read only

Read only buffers are very simple. You can read them, but you can't write data to them. You can call the buffer
The asReadOnlyBuffer() method of the buffer converts any conventional buffer into a read-only buffer. This method returns
Returns a buffer that is exactly the same as the original buffer and shares data with the original buffer, but it is read-only.
If the contents of the original buffer change, the contents of the read-only buffer also change

Tags: Java NIO TCP/IP

Posted on Tue, 21 Sep 2021 13:48:15 -0400 by andyhajime