`
ryanflyer
  • 浏览: 101036 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

NIO Buffer and Channel

 
阅读更多

 

1.Buffer类图



 新创建的ByteBuffer,四个属性的位置


capacity:容量,指定缓冲区的大小。

 

ByteBuffer byteBuffer = ByteBuffer.allocate(BUFFER_SIZE);

 limit:第一个不应该读取或写入的元素的索引。缓冲区的限制不能为负,并且不能大于其容量。

 

Position: 下一个要读取或写入的元素的索引。缓冲区的位置不能为负,并且不能大于其限制。

 

遵循条件:0 <= 标记 <= 位置 <= 限制 <= 容量

 

不同的方法都是编辑buffer,移动这些标记。有四个方法需要重点关注

 

Buffer.clear();
Buffer.compact();
Buffer.flip();
Buffer.rewind();

clear(); 

  • 使缓冲区为一系列新的通道读取或相对放置 操作做好准备:它将限制设置为容量大小,将位置设置为 0。 这意味着新数据会覆盖旧数据。

compact(); The compact method moves the elements between the current position and the limit to the begging of the buffer.

flip(); The flip method need to be called before reading the data from the buffer. 

  • 使缓冲区为一系列新的通道写入或相对获取 操作做好准备:它将限制设置为当前位置,然后将位置设置为 0。

rewind(); 

  • 使缓冲区为重新读取已包含的数据做好准备:它使限制保持不变,将位置设置为 0。 

Direct vs. nonDirect buffers: 

字节缓冲区要么是直接的,要么是非直接的。如果为直接字节缓冲区,则 Java 虚拟机会尽最大努力直接在此缓冲区上执行本机 I/O 操作。也就是说,在每次调用基础操作系统的一个本机 I/O 操作之前(或之后),虚拟机都会尽量避免将缓冲区的内容复制到中间缓冲区中(或从中间缓冲区中复制内容)。

直接字节缓冲区可以通过调用此类的 allocateDirect 工厂方法来创建。此方法返回的缓冲区进行分配和取消分配所需成本通常高于非直接缓冲区。

 

NonDirect: if you create a buffer that will not interact with native resource (ex. Just to store a String) you should use a NonDirect Buffer.

Adding to a Buffer: When adding data to a buffer you can use the wrap() method. Note that when a buffer is created by wrapping it are never direct.

/* * wraps a string inside an buffer.
*/
String string = "Text to be added";
CharBuffer charBuffer = CharBuffer.allocate(string.length());
charBuffer.wrap(string);

or you could wrap entire blocks of data in a form of an array:

/* * takes a byte array and wraps it into a buffer.
*/
byte[] data = “Text to be added”.getBytes(“UTF-8”);
ByteBuffer buffer1 = ByteBuffer.wrap(data);

Draining a Buffer: Buffers can be drained into any data type:

/* * uses the get() method to fill a string.
*/
String fromBuffer = “”;
while (buffer.hasRemaining()) {
fromBuffer += buffer.get();
}

Data Conversion: Data Conversion is an important aspect of buffers. You can use the factory methods to change a buffer from one type of another:

ByteBuffer byteBuffer = ByteBuffer.allocate(5); 

IntBuffer intBuffer = byteBuffer.asIntBuffer();

flip方法:首先将限制设置为当前位置,然后将位置设置为 0。

2.Channel

通道只能在字节缓冲区上操作。

I/O可以分为广义的两大类别:File I/O和Stream I/O。相应地有两种类型的通道文件(file)通道和套接字(socket)通道。FileChannel类和三个socket通道类:SocketChannel、ServerSocketChannel和DatagramChannel。

 

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

 

 

  • FileChannel对象是线程安全(thread-safe)的。多个进程可以在同一个实例上并发调用方法而不会引起任何问题,不过并非所有的操作都是多线程的(multithreaded)。影响通道位置或者影响文件大小的操作都是单线程的(single-threaded)。文件锁定模型,锁的对象是文件而不是通道或线程,这意味着文件锁不适用于判优同一台Java虚拟机上的多个线程发起的访问。锁与文件关联,而不是与通道关联。我们使用锁来判优外部进程,而不是判优同一个Java虚拟机上的线程。
  • Socket Channel。请注意DatagramChannel和SocketChannel实现定义读和写功能的接口而ServerSocketChannel不实现。ServerSocketChannel负责监听传入的连接和创建新的SocketChannel对象,它本身从不传输数据。

为了加深理解,自己写了一个小示例代码实现本地文件拷贝,类似上传:

 

package com.zhang.nio;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * 使用NIO上传文件
 * <p />
 * 
 * @author Administrator
 */
public class UploadFile {

    private final static int DEFAULT_CAPACITY = 8092;

    private final static String SOURCE_FILE_PATH = "F:\\开发工具\\spring-framework-3.0.5.RELEASE-with-docs.zip";

    private final static String DEST_PATH = "F:\\test\\test.zip";

    /**
     * @param args
     */
    public static void main(String[] args) {
        ByteBuffer buffer = ByteBuffer.allocateDirect(DEFAULT_CAPACITY);
        FileInputStream inputStream = null;
        FileOutputStream outputStream = null;
        FileChannel inChannel = null;
        FileChannel outChannel = null;
        try {
            inputStream = new FileInputStream(SOURCE_FILE_PATH);
            outputStream = new FileOutputStream(DEST_PATH);
            inChannel = inputStream.getChannel();
            outChannel = outputStream.getChannel();
            while (inChannel.read(buffer) != -1) {
                buffer.flip();
                outChannel.write(buffer);
                buffer.clear();
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {

            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
                if (inChannel != null) {
                    inChannel.close();
                }
                if (outChannel != null) {
                    outChannel.close();
                }

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}
 

 

 

 

  • 大小: 36.8 KB
  • 大小: 8.5 KB
  • 大小: 96.1 KB
分享到:
评论

相关推荐

    NIO详细介绍channle,buffer,Selector

    主要介绍一些关于NIO 的基础知识,有浅到深

    Java IO, NIO and NIO.2(Apress,2015)

    Next, you'll learn about NIO's buffer, channel, selector, regular expression, charset, and formatter APIs. Finally, you'll discover NIO.2's offerings in terms of an improved file system interface, ...

    尚硅谷Java视频_NIO 视频教程

    尚硅谷_NIO_缓冲区(Buffer)的数据存取 ·03. 尚硅谷_NIO_直接缓冲区与非直接缓冲区 ·04. 尚硅谷_NIO_通道(Channel)的原理与获取 ·05. 尚硅谷_NIO_通道的数据传输与内存映射文件 ·06. 尚硅谷_NIO_分散读取与聚集...

    java网络编程NIO视频教程

    03-Java NIO-Channel-概述.mp4 04-Java NIO-Channel-FileChannel(介绍和示例).mp4 05-Java NIO-Channel-FileChannel详解(一).mp4 06-Java NIO-Channel-FileChannel详解(二).mp4 07-Java NIO-Channel-Socket通道-概述...

    Java NIO实战开发多人聊天室

    05-Java NIO-Channel-FileChannel详解(一).mp4 06-Java NIO-Channel-FileChannel详解(二).mp4 08-Java NIO-Channel-ServerSocketChannel.mp4 09-Java NIO-Channel-SocketChannel.mp4 10-Java NIO-Channel-...

    Java性能优化之使用NIO提升性能(Buffer和Channel)

    NIO是NewI/O的简称,具有以下特性:为所有的原始类型提供(Buffer)缓存支持;使用java.nio.charset.Charset作为字符集编码解码解决方案;增加通道(channel)对象,作为新的原始I/O抽象;支持锁和内存映射文件的...

    JavaNIO chm帮助文档

    Java NIO系列教程(二) Channel Java NIO系列教程(三) Buffer Java NIO系列教程(四) Scatter/Gather Java NIO系列教程(五) 通道之间的数据传输 Java NIO系列教程(六) Selector Java NIO系列教程(七) ...

    java nio中文版

    java NIO是 java New IO 的简称,在 jdk1.4 里提供的新 api 。 Sun 官方标榜的特性如下: – 为所有的原始类型提供 (Buffer) 缓存支持。 – 字符集编码解码解决方案。 – Channel :一个新的原始 I/O 抽象。 – 支持...

    java NIO 视频教程

    标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。 Java NIO: Non-blocking IO(非阻塞IO) Java NIO...

    Java NIO系列教程

    Java NIO系列教程 Java NIO Channel Buffer Selector SocketChannel

    Java+NIO+中文版.pdf

    java nio作者倾力所写的简单易懂的NIO学习指南,让你顺利拿下NIO开发,包括了NIO中的Buffer,Channel,Selector的介绍,理论&代码都有,是你学习NIO的不二法宝~

    java nio教程pdf

    标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。 Java NIO: Asynchronous IO(异步IO) Java NIO可以...

    NIO实现多用户聊天demo,通过demo深入理解NIO三大组件:buffer、channel、selector

    目录运行效果截图:源代码:Server端:Client端:使用时注意:(持续更新) 运行效果截图: 启动server端: 依次启动client1、client2、client3并输入相应昵称...import java.nio.channels.Channel; import java.nio.c

    基于Nio的多人聊天Demo

    实现多人聊天消息转发,用户发送消息同步到服务中的其他客户端,运用到了nio中buffer、socket、selector。 1、Channel,管道。Channel可以理解为连接,与BIO中Sokcet类似,一个连接对应一个Channel,但Channel中仍...

    <<java nio>> javaNIO的使用

    javaNIO的使用,讲述了新IO,Buffer ,channel的核心概念

    JAVA IO-NIO 详解

    NIO的核心组件包括Channel(通道)、Buffer(缓冲区)和Selector(选择器)。Channel是数据传输的通道,它替代了传统IO中的流;Buffer是数据的容器,它可以在Channel和程序之间进行数据的读写操作;Selector则用于...

    浅谈java中nio的使用方式

    NIO其核心概念包括Channel,Selector,SelectionKey,Buffer.

    JAVA的IO与NIO

    nio与io的区别 Channel Buffer 事件及nio的非阻塞读取

Global site tag (gtag.js) - Google Analytics