`
shifulong
  • 浏览: 59196 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

nio学习记录 : start(buffer channel selector)

    博客分类:
  • java
 
阅读更多

Buffer的capacity,limit,position

limit,position的含义取决于是读模式还是写模式

 

capacity

buffer的大小

 

limit

write:和capacity一样,表示能写多少

read:表示最多可读多少

 

position

write:write index,最大值 capacity-1

read:read index,从写模式切换到读模式时,position会被重置为0

 

 

buffer的类型

  • ByteBuffer
  • MappedByteBuffer
  • CharBuffer
  • DoubleBuffer
  • FloatBuffer
  • IntBuffer
  • LongBuffer
  • ShortBuffer
public class FileTest {

    public static void main(String[] args) throws IOException {

        RandomAccessFile raFile = new RandomAccessFile("/Users/shifulong/monitor_contact.sql", "rw");
        FileChannel fileChannel = raFile.getChannel();
        ByteBuffer byteBuffer = ByteBuffer.allocate(64);
        
        while (fileChannel.read(byteBuffer) != -1) {//read in to buffer

            byteBuffer.flip();

            while (byteBuffer.hasRemaining()) {
                System.out.print((char) byteBuffer.get());
            }

            byteBuffer.clear();
        }
    }
}

 

 

典型的几个方法

ByteBuffer byteBuffer = ByteBuffer.allocate(64);//获取一个64大小的buffer

byteBuffer.flip();//将buffer从写模式切换到读模式

byteBuffer.rewind();//将position设为0,可重读数据

byteBuffer.clear();//清除buffer position设为0,如果buffer中还有数据没有读,就丢失了
byteBuffer.compact();//清除buffer,并把没读的数据copy到起始处,position设到最后一个没读的数据后面,可以追加写

byteBuffer.mark();//标记一个特定postion
byteBuffer.reset();//恢复标记,恢复到标记的position

 

 分散&聚集

多个buffer写到channel中

从channel总读到多个buffer中

//分散
public void scatter() throws IOException {

    RandomAccessFile randomAccessFile = new RandomAccessFile("", "");
    FileChannel fileChannel = randomAccessFile.getChannel();

    ByteBuffer head = ByteBuffer.allocate(16);
    ByteBuffer body = ByteBuffer.allocate(64);

    fileChannel.read(new ByteBuffer[]{head, body});//读到多个buffer中,不方便操作不定长的消息
}

//聚集
public void gather() throws IOException {

    RandomAccessFile randomAccessFile = new RandomAccessFile("", "");
    FileChannel fileChannel = randomAccessFile.getChannel();

    ByteBuffer buffer1 = ByteBuffer.allocate(16);//need put byte to buffer
    ByteBuffer buffer2 = ByteBuffer.allocate(64);

    fileChannel.write(new ByteBuffer[]{buffer1, buffer2});//多个buffer写到channel,可以操作不定长的消息
}

 

通道之间的数据传输

只要两个通道之间有一个是FileChannel,就可以将一个channel传输到另一个channel

    public static void from() throws IOException {
        RandomAccessFile fromFile = new RandomAccessFile("/Users/shifulong/monitor_contact.sql", "rw");
        FileChannel fromChannel = fromFile.getChannel();

        RandomAccessFile toFile = new RandomAccessFile("/Users/shifulong/monitor_contact_to.sql", "rw");
        FileChannel toChannel = toFile.getChannel();

        long position = 0;

        toChannel.transferFrom(fromChannel,position,fromChannel.size());
        toChannel.close();
        fromChannel.close();
    }

    public static void to() throws IOException {

        RandomAccessFile fromFile = new RandomAccessFile("/Users/shifulong/monitor_contact.sql", "rw");
        FileChannel fromChannel = fromFile.getChannel();

        RandomAccessFile toFile = new RandomAccessFile("/Users/shifulong/monitor_contact_to.sql", "rw");
        FileChannel toChannel = toFile.getChannel();

        long position = 0;
        fromChannel.transferTo(position,toChannel.size(),toChannel);
        fromChannel.close();
        toChannel.close();
    }

 

selector

Selector selector = Selector.open();
SelectableChannel channel = null;// TODO
channel.configureBlocking(false);//非阻塞模式

//channel注册selector,第二个参数是intreast事件,多个intreast事件可以用“|”
//  int intreastSetP = SelectionKey.OP_ACCEPT | SelectionKey.OP_READ;
SelectionKey selectionKey1 = channel.register(selector, SelectionKey.OP_READ);

int intreastSet = selectionKey1.interestOps();

int readySet = selectionKey1.readyOps();

//添加附加对象
selectionKey1.attach(new Object());
//取出附加对象
selectionKey1.attachment();

//选取通道
selector.select();//block when at least a ready channel that you regist
selector.select(1000);//timeout
selector.selectNow();//return immediately

Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
while (iterator.hasNext()) {
    SelectionKey selectionKey = iterator.next();
    if (selectionKey.isAcceptable()) {
        // 这两个含义不太清楚
    } else if (selectionKey.isConnectable()) {
        // 这两个含义不太清楚
    } else if (selectionKey.isReadable()) {
        // a channel is ready for reading
    } else if (selectionKey.isWritable()) {
        // a channel is ready for writing
    }
    iterator.remove();

    SelectableChannel selectableChannel = selectionKey.channel();
} 

whole demo

public void selectTest() throws IOException {
    Selector selector = Selector.open();
    SelectableChannel channel = null;
    channel.register(selector, SelectionKey.OP_READ);
    while (true) {
        int readyChannels = selector.select();
        if (readyChannels == 0) continue;
        Set<SelectionKey> selectedKeys = selector.selectedKeys();
        Iterator<SelectionKey> iteratror = selectedKeys.iterator();
        while (iteratror.hasNext()) {
            SelectionKey selectionKey = iteratror.next();
            if (selectionKey.isReadable()) {
                // TODO
            }
            iteratror.remove();
        }
    }
}
 

 pipe

//两个线程的单向数据连接
public void pipePractice() throws IOException {
    Pipe pipe = Pipe.open();
    Pipe.SinkChannel sinkChannel = pipe.sink();
    writeToSonk();

    Pipe.SourceChannel sourceChannel = pipe.source();
    readFromSource();

}
private void readFromSource() {
    // TODO
}
private void writeToSonk() {
    // TODO
}

 

 

 

 

  • 大小: 15.8 KB
  • 大小: 7.6 KB
分享到:
评论

相关推荐

    Java NIO.docx

    Java NIO 是 JDK 1.4 中引入的新的 IO 方式,它主要包含 Buffer、Channel、Selector 三个核心的组件。 Java NIO 概述 ---------------- Java NIO 是 Java 编程语言中的一种新的 IO 模式,它与传统 IO 的区别在于...

    Java NIO原理解析

    NIO的核心概念包括通道(Channel)、缓冲区(Buffer)和选择器(Selector)。 1. **通道(Channel)**:在Java NIO中,通道代表了一个打开的I/O连接,如文件、套接字、网络流等。通道是双向的,数据可以从通道读取...

    NIO与传统IO代码区别实例

    NIO的核心组件包括通道(Channel)、缓冲区(Buffer)和选择器(Selector)。通道类似于流,但可以同时读写数据,而缓冲区则用于存储数据,选择器则能监控多个通道的状态,一旦某个通道准备好读写,选择器就会通知...

    nSocket:一个nio框架,学习用

    NIO的核心组件包括选择器(Selector)、通道(Channel)和缓冲区(Buffer)。 ### 2. nSocket框架特性 - **异步通信**:nSocket采用NIO的非阻塞模式,使得服务器可以同时处理多个客户端连接,提高了系统资源利用率...

    java面试宝典

    3. NIO:了解非阻塞I/O,包括Channel、Buffer和Selector的使用。 五、反射与注解 1. 反射:理解反射机制,如何动态获取和调用类、方法、字段的信息。 2. 注解:学习自定义注解和元注解,理解注解在代码解耦和运行时...

    java api中文文档

    - NIO(New IO):提供非阻塞I/O操作,包括通道(Channel)、缓冲区(Buffer)和选择器(Selector)。 9. **XML处理**: - DOM解析:将整个XML文档加载到内存中,通过Document对象进行操作。 - SAX解析:事件...

    core java1&2

    3. **高级I/O(NIO)**:介绍非阻塞I/O模型,Channel、Buffer和Selector的使用。 4. **反射与注解**:如何在运行时检查类和对象的信息,以及如何使用注解来添加元数据。 5. **Java数据库连接(JDBC)**:连接和...

    mina2.x开发示例

    NIO的核心概念包括Selector、Channel和Buffer,它们是Mina处理网络通信的基础。 2. **Session和Protocol Buffers**:在Mina中,Session代表一个网络连接,用于管理连接状态和传输数据。Protocol Buffers是Google...

    Java 执行本地脚本携带多参数

    Java NIO是一种I/O模型,它提供了选择器(Selector)、通道(Channel)和缓冲区(Buffer)等机制,可以在单线程中处理多个连接,显著提高了服务器处理高并发连接的能力。与传统的阻塞I/O模型相比,NIO允许应用程序在...

    java多线程文件传输

    - **NIO(非阻塞I/O)**:提供了一种新的I/O模型,可以提高文件传输效率,如`Channel`、`Buffer`和`Selector`等。 - **多线程文件传输策略**:可以创建多个线程分别处理文件的不同部分,提高传输速度。 6. **性能...

    java socket 通信

    同时,Java的`java.nio`包提供了更高级的Socket通信工具,如Selector和Channel,可以更好地管理多个Socket连接。 总的来说,Java Socket通信是网络编程的基础,理解其原理和使用方法对于开发网络应用程序至关重要。...

    java核心知识点整理.pdf

    1. 目录 1. 2. 目录 .........................................................................................................................................................1 JVM .........................

    JAVA核心知识点整理(有效)

    1. 目录 1. 2. 目录 .........................................................................................................................................................1 JVM ........................

Global site tag (gtag.js) - Google Analytics