通道

通道

通道是nio的第二个主要创新。channel用于字节缓冲区和位于另一侧的实体进行有效的传递数据。通常情况下,

首先,看一下基本的Channel接口,下面是Channel接口的完整源码:

package java.nio.channels;

import java.io.IOException;
import java.io.Closeable;

public interface Channel extends Closeable {

    public boolean isOpen();

    public void close() throws IOException;

}

 和缓冲区不同,通道的api主要是由接口指定。在不同的操作系统上通道实现会有根本性的差异,所以通道api仅仅描述了可以做什么,因此通道实现经常使用操作系统的本地代码,通道接口允许开发者以一种受控且可移植的方式来访问底层的io服务。

对于所有通道来说只有两种共同的操作:检查一个通道是否打开isOpen和关闭一个打开的通道close,其余的都是那些实现channel接口以及它的子接口的类。

和缓冲区不同,通道API主要由接口指定。不同的操作系统上通道实现会有根本性的差异,所以通道API仅仅描述了可以做什么,因此很自然地,通道实现经常使用操作系统的本地代码,通道接口允许开发者以一种受控且可移植的方式来访问底层的I/O服务。

可以从底层的Channel接口看到,对所有通道来说只有两种共同的操作:检查一个通道是否打开isOpen()和关闭一个打开的通道close(),其余所有的东西都是那些实现Channel接口以及它的子接口的类。

从Channel接口引申出的其他接口都是面向字节的子接口:

包括WritableByteChannel和ReadableByteChannel。这也正好支持了我们之前的所学:通道只能在字节缓冲区上操作。层次接口表明其他数据类型的通道也可以从Channel接口引申而来。这是一种很好的镭射机,不过非字节实现是不可能的,因为操作系统都是以字节的形式实现底层I/O接口的。

认识通道

看一下基本的接口:

public interface WritableByteChannel extends Channel{
    public int write(ByteBuffer src) throws IOException;
}
public interface ReadableByteChannel extends Channel {
    public int read(ByteBuffer dst) throws IOException;
}
public interface ByteChannel extends ReadableByteChannel, WritableByteChannel{
}

通道可以是单向的也可以是双向的。一个Channel类可能实现定义read()方法的ReadableByteChannel接口,而另一个Channel类也许实现WritableByteChannel接口以提供write()方法。实现这两种接口其中之一的类都是单向的,只能在一个方向上传输数据。如果一个类同时实现这两个接口,那么它是双向的,可以双向传输数据,就像上面的ByteChannel。通道可以以阻塞(blocking)或非阻塞(nonblocking)模式运行,非阻塞模式的通道永远不会让调用的线程休眠,请求的操作要么立即完成,要么返回一个结果表明未进行任何操作。只有面向流的(stream-oriented)的通道,如sockets和pipes才能使用非阻塞模式

认识文件通道

通道是访问I/O服务的导管,I/O可以分为广义的两大类:File I/O和Stream I/O。那么相应的,通道也有两种类型,它们是文件(File)通道和套接字(Socket)通道。文件通道指的是FileChannel,套接字通道则有三个,分别是SocketChannel、ServerSocketChannel和DatagramChannel。

通道可以以多种方式创建。Socket通道可以有直接创建Socket通道的工厂方法,但是一个FileChannel对象却只能通过在一个打开的RandomAccessFile、FileInputStream或FileOutputStream对象上调用getChannel()方法来获取,开发者不能直接创建一个FileChannel

文件I/O是我们最常使用的I/O,因此这部分先认识一下文件通道,下一部分再以代码形式演示如何使用文件通道高。用UML图表示一下文件通道的类层次关系:

文件通道总是阻塞式的,因此不能被置于非阻塞模式下

前面提到过了,FileChannel对象不能直接创建,一个FileChannel实例只能通过在一个打开的File对象(RandomAccessFile、FileInputStream或FileOutputStream)上调用getChannel()方法获取,调用getChannel()方法会返回一个连接到相同文件的FileChannel对象,且该FileChannel对象具有与file对象相同的访问权限,然后就可以使用通道对象来利用强大的FileChannel API了。

通道只能使用ByteBuffer

原文地址:https://www.cnblogs.com/tp123/p/6434834.html