zoukankan      html  css  js  c++  java
  • 通道

    通道

    通道是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

  • 相关阅读:
    如何理解联合文件系统?
    Docker 学习笔记(一)
    Bzoj 3124: [Sdoi2013]直径 题解
    Bzoj 3131 [Sdoi2013]淘金 题解
    欧拉路(题目)
    硬币问题
    线段树、树状数组
    Splay树、Treap树
    模拟退火
    广搜题目(一本通)
  • 原文地址:https://www.cnblogs.com/tp123/p/6434834.html
Copyright © 2011-2022 走看看