java-NIO 学习(chapter1)
来源:互联网 发布:网络挣钱游戏 编辑:程序博客网 时间:2024/04/28 23:11
java-NIO 学习(chapter1)
发现写的有点乱,大家各取所需 - - !
一,nio 是New I/O 的简称,在jdk1.4版本后开始提供,位于java.nio.*包中。其目的就是为了提高文件和网络I/O的速度,如果你在代码中使用了老I/O的FileInputStream,FileOutputStream,RandomAccessFile三个类时,你不用去纠结要不要用NIO去替换他们,因为这三类已经用NIO重新写过了。
二,java NIO由缓冲区(Buffer)、通道(Channel)、选择器(Selector)核心组成,用《Tinking in Java》中的话来解释他们的关系:想象有一个煤矿,通道是包含煤矿的矿藏,而缓冲器则是派送到矿藏的卡车,卡车满载煤矿而归,我们再从卡车上获得煤矿,我们并没有和通道进行交互,我们只和缓冲器交互,把缓冲器派送到通道,通道要么从缓冲器获得数据,要么向缓冲器发送数据。不过作者并没有解释Selector在其中的定义,稍后我会在学习后加以补充。
三,首先来看下Channel ,看下官方文档的定义:
A channel represents an open connection to an entity such as a hardware device, a file, a network socket, or a program component that is capable of performing one or more distinct I/O operations, for example reading or writing.//通道表示连到一个实体(例如:硬件设备、文件、网络套接字或者能执行一个或多个不同 I/O 操作(例如:读或写)的程序组件)的开放连接。(感觉和没说一样。。。。)
先看个channel 的简单实例吧,中间有用到buffer,会在后面详解。
public class Main { public static final int BUFFER_SIZE = 4; public static void main(String[] args) throws Exception { // test channel File file = new File("C:\\Users\\Administrator\\Desktop\\testOut.txt"); FileInputStream inputStream = new FileInputStream(file); FileChannel channel = inputStream.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE); //创建缓冲区 int size = 0; while ((size =channel.read(buffer)) != -1) {// System.out.println(size); buffer.flip(); //这个会在后面详解,反正现在记住,写模式切换到读模式时,要调用flip()方法 while (buffer.hasRemaining()){ System.out.println((char)buffer.get()); } buffer.clear();//读模式切换到写模式,清空buffer } channel.close(); inputStream.close(); }}
上面的代码我们用到了FileChannel,实际上在JDK中Channel只是一个interface, 实现了Channel接口的类有:
其中最重要的几个类:
- DatagramChannel 能通过UDP读写网络中的数据
- FileChannel 从文件中读写数据
- SocketChannel 能通过TCP读写网络中的数据。
- ServerSocketChannel 可以监听新进来的TCP连接,像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel。
从上面的代码中,发现channel 有点类似Stream,但其实还是有很多的不同之处:
- channel既可以读数据,也可以写数据。Stream的读写则是单向的
- channel可以异步的读写
- channel 总是要和buffer交互,要么从buffer中读数据,要么从buffer中写数据
我们可以异步地关闭和中断 NIO 通道。所以,如果一个线程在某条通道的 I/O 操作上阻塞时,那么另一个线程可以将这条通道关闭。类似地,如果一个线程在某条通道的 I/O 操作上阻塞时,那么另一个线程可以中断这个阻塞线程。
四,Buffer,从上面的例子和章节中,我们可以知道,buffer 主要用来和Channel 进行交互,数据可以从Channel 读入到buffer中,也可以从buffer 写入 channel。
buffer 本质上其实就是一块可以进行读写的内存(Heap),只是被包装成Buffer对象,并提供了一组方法,用来进行对改内存的访问。
从上面channel的代码中发现,buffer的使用一般分为5个步骤:
- 1.创建:调用自身的静态工厂方法创建buffer
- 2.读取数据到buffer: 调用channel的read()方法
- 3.切换模式,调用自身的flip()方法
- 4.从buffer中读取数据
- 5.清空buffer。(从某种意义上说并不是清空)调用 clear()和compact()方法(后面解释这两者的区别)
234
0 0
- java-NIO 学习(chapter1)
- Java NIO Chapter1 Learning Tips
- Java SE 学习 chapter1
- chapter1(JAVA语言程序设计)
- Java多线程编程学习chapter1
- Java入门(二)chapter1
- Java NIO学习(一)
- Java NIO 学习(一)
- Java NIO 学习(二)
- Java NIO 学习(三)
- Java NIO 学习(四)
- java nio学习(一)
- java nio学习(二)
- java nio学习(三)
- java nio学习(五)
- java nio学习(六)
- java nio学习(七)
- java nio学习(八)
- iOS textfield 限定输入的文本长度
- 【C#】反射应用-通过方法名调用方法
- unity 血条遮挡问题
- [angularJS]我的第一个angularJS应用——解决不执行controller的代码
- 【常用工具类】读取验证码并自动填充 EditText
- java-NIO 学习(chapter1)
- sklearn pipline
- iOS cellForRowAtIndexPath 不调用原因分析
- 曾读过但并不代表精通的书及资料
- 利用Java的反射与代理机制实现IOC
- 寒假
- Java内存模型FAQ(八)Final字段如何改变它们的值
- UNDERSTANDING CONVOLUTIONAL NEURAL NETWORKS FOR NLP
- setUserVisibleHint 解决预加载问题