Junior sister learning javaio: the wonderful use of channel in NiO

brief introduction

Younger martial sister, do you remember our initial intention of using IO and NiO?

Younger martial sister: Senior brother F, don't you use IO and NiO to make life better and the world full of love? Let me and other programmers can gracefully move data from one place to another. Only by sharpening their tools and doing good things can we have more time to enjoy life.

Good, if the data is compared with being a man, the purpose of IO and NiO is to transport people to the United States.

Younger martial sister: elder martial brother F, why should we ship it to the United States? The new crown in the United States is too serious now. We'd better stay in China. China is the safest country in the world!

Well, to be on the safe side, we'll ship people to Shanghai. People are data. How can they be transported? You can take planes, cars and trains. These planes, cars and trains can be regarded as buffers one by one.

Finally, the route of the plane, the road of the car and the track of the train can be regarded as channels.

More highlights:

To put it simply, channel is the channel responsible for transporting buffers.

IO can be divided into two types by source: file IO from file and stream IO from stream. No matter what kind of IO, data can be transported through the channel.

Channel classification

Although there are only two sources of data, there are many channels in the JDK, as shown in the following figure:

Let's take a look at the most basic and top-level interface channel:

public interface Channel extends Closeable {
    public boolean isopen();
    public void close() throws IOException;

}

The top-level channel is very simple. It inherits the closeable interface and needs to implement two methods, ispen and close.

One is used to determine whether the channel is open and the other is used to close the channel.

Younger martial sister: Senior brother F, why is the channel on the top floor so simple? It doesn't conform to the complex human design of the channel.

Don't worry, JDK actually makes sense, because it is a top-level interface, which must be more abstract and more general. As a result, when it is general, it is found that only these two methods are general.

Therefore, in order to solve this problem, many different types are defined in channel.

There are five types of channels at the bottom layer, namely:

FileChannel

Among the five channels, the filechannel is related to the file.

Filechannel can be obtained from RandomAccessFile, FileInputStream or fileoutputstream by calling getchannel ().

You can also directly call the open method in filechannel to pass in path creation.

public abstract class FileChannel
    extends AbstractInterruptibleChannel
    implements SeekableByteChannel,GatheringByteChannel,ScatteringByteChannel

Let's look at the interfaces and classes inherited or implemented by filechannel.

Abstractinterruptiblechannel implements the interruptiblechannel interface. As we all know, interrupt is a sharp tool used to interrupt thread execution. Let's take a look at the following very mysterious Code:

protected final void begin() {
        if (interruptor == null) {
            interruptor = new Interruptible() {
                    public void interrupt(Thread target) {
                        synchronized (closeLock) {
                            if (closed)
                                return;
                            closed = true;
                            interrupted = target;
                            try {
                                AbstractInterruptibleChannel.this.implCloseChannel();
                            } catch (IOException x) { }
                        }
                    }};
        }
        blockedOn(interruptor);
        Thread me = Thread.currentThread();
        if (me.isInterrupted())
            interruptor.interrupt(me);
    }

The above code is the core of abstractinterruptible channel.

Firstly, an instance of interruptible is defined. In this instance, there is an interrupt method to close the channel.

Then obtain the instance of the current thread and judge whether the current thread is interrupted. If so, call the interrupt method of interruptible to close the current channel.

Seekablebytechannel is used to connect an entry or file. It has a unique attribute called position, which represents the current read position. Can be modified.

Gatheringbytechannel and scatteringbytechannel indicate that one buffer sequence can be read and written at a time (buffer array):

public long write(ByteBuffer[] srcs,int offset,int length)
        throws IOException;
public long read(ByteBuffer[] dsts,int length)
        throws IOException;

Selector and channel

Before talking about other channels, let's look at a selector related to the following channels:

Here we will introduce a new channel type called selectablechannel. The previous filechannel connection is one-to-one, that is, a channel corresponds to a processing thread. The selectablechannel is one to many, that is, a processing thread can process multiple channels through the selector.

Selectablechannel can monitor multiple channels by registering different selectionkeys. We will explain the use of selector in detail later. Please look forward to it.

DatagramChannel

Datagram channel is a channel used to handle UDP. It comes with an open method to create an instance.

Let's take a look at the definition of datagram channel:

public abstract class DatagramChannel
    extends AbstractSelectableChannel
    implements ByteChannel,ScatteringByteChannel,MulticastChannel

Bytechannel means that it is both readablebytechannel and writablebytechannel, and can be written and read at the same time.

Multicastchannel represents a multicast protocol. Exactly corresponds to UDP.

SocketChannel

Socketchannel is a channel used to handle TCP. It is also created through the open method.

public abstract class SocketChannel
    extends AbstractSelectableChannel
    implements ByteChannel,NetworkChannel

The only difference between socketchannel and datagram channel is that it implements networkchannel.

Networkchannel provides some network socket operations, such as binding addresses.

ServerSocketChannel

Serversocketchannel is also a networkchannel, which is mainly used for listening on the server side.

public abstract class ServerSocketChannel
    extends AbstractSelectableChannel
    implements NetworkChannel

AsynchronousSocketChannel

Finally, asynchronous socketchannel is an asynchronous channel:

public abstract class AsynchronousSocketChannel
    implements AsynchronousByteChannel,NetworkChannel

Why asynchronous? Let's look at a method:

public abstract Future<Integer> read(ByteBuffer dst);

You can see that the return value is a future, so the read method can return immediately and only take values from future when we need them.

Using channel

Younger martial sister: Senior brother F, I'm dazzled by so many kinds of channels. Can you tell me a specific example of channel?

OK, younger martial sister, let's talk about an example of using channel to copy files. Although channel provides the method of transferto, which can be very simple to copy, in order to see the general use of channel, we choose a more conventional example:

public void useChannelcopy() throws IOException {
        FileInputStream input = new FileInputStream ("src/main/resources/www.flydean.com");
        FileOutputStream output = new FileOutputStream ("src/main/resources/www.flydean.com.txt");
        try(ReadableByteChannel source = input.getChannel(); WritableByteChannel dest = output.getChannel()){
            ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
            while (source.read(buffer) != -1)
            {
                // flip buffer,准备写入
                buffer.flip();
                // 查看是否有更多的内容
                while (buffer.hasRemaining())
                {
                    dest.write(buffer);
                }
                // clear buffer,供下一次使用
                buffer.clear();
            }
        }
    }

In the above example, we read the buffer from InputStream and then write it to fileoutputstream.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>