2021-08-09笔记

3. NIO

3.1简介

NIO是JDK1.4的时候出现了一个新的IO,用来代替传统的IO流。

NIO是基于通道(Channel),面向缓冲区(Buffer)的。

在JDK1.7的时候,为NIO添加了一些新的特定。被称为NIO.2

3.2 NIO组成

Channels:通道 Buffer:缓冲区 Selectors:选择器

Channels和Buffer是新IO中的两个核⼼对象,Channel是对传统的输⼊/输出系统的模拟,在新IO系统中所有的数据都需要通过通道传输。

Channels与传统的 InputStream , OutputStrem 最⼤的区别在于它提供了⼀个map()⽅法,通过该map()⽅法可以直接将"⼀块数据"映射到 内存中,如果说传统的输⼊/输出系统是⾯向流处理,则新IO则是⾯向块的处理 。

Buffer可以被理解为⼀个容器(缓冲区,数组),发送到Channel中的所有对象都必须⾸先 放到Buffer中,⽽从Channel中读取的数据也必须 放到Buffer中,也就是说数据可以从Channel读取到Buffer中,也可以从Buffer写到 Channel中。

3.3 和传统的IO区别

1.IO⾯向流,NIO⾯向缓冲区
Java IO⾯向流意味着每次从流中读⼀个或多个字节,直⾄读取所有字节,它们没有被
缓存在任何地⽅。此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数
据,需要先将它缓存到⼀个缓冲区。 Java NIO的缓冲导向⽅法略有不同。数据读取到
⼀个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活
性.
2.IO是阻塞式的,NIO有⾮阻塞式的
Java IO的各种流是阻塞的。这意味着,当⼀个线程调⽤read() 或 write()时,该
线程被阻塞,直到有⼀些数据被读取,或数据完全写⼊。该线程在此期间不能再⼲任何事
情了。Java NIO的⾮阻塞模式,使⼀个线程从某通道发送请求读取数据,但是它仅能得
到⽬前可⽤的数据,如果⽬前没有数据可⽤时,就什么都不会获取,⽽不是保持线程阻塞
所以直⾄数据变的可以读取之前,该线程可以继续做其他的事情。 ⾮阻塞写也是如此。
3.IO没有选择器,NIO有选择器
Java NIO的选择器允许⼀个单独的线程来监视多个输⼊通道,你可以注册多个通道使⽤
⼀个选择器,然后使⽤⼀个单独的线程来“选择”通道:这些通道⾥已经有可以处理的输
⼊,或者选择已准备写⼊的通道。这种选择机制,使得⼀个单独的线程很容易来管理多个
通道.

4. Buffer缓冲区

4.1缓冲区的概念

其实是⼀个⽤来存储基本数据类型的⼀个容器, 类似于⼀个数组。

缓冲区, 可以按照存储的数据类型不同, 将缓冲区分为:

ByteBuffer、 ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、 DoubleBuffer、CharBuffer

但是, 要注意, 并没有BooleanBuffer

这些缓冲区, 虽然是不同的类, 但是他们拥有的相同的属性和⽅法。 因为他们都继 承⾃相同的⽗类 Buffer。

4.2 Buffer的几个属性

  • capacity: 容量。 代表⼀个缓冲区的最⼤的容量, 缓冲区⼀旦开辟完成, 将⽆法修改。

  • limit: 限制。 表示缓冲区中有多少数据可以操作。

  • position: 位置。 表示当前要操作缓冲区中的哪⼀个下标的数据。

  • mark: 标记。 在缓冲区中设计⼀个标记, 配合 reset() ⽅法使⽤, 修改position 的值

4.3 Buffer常用的方法

方法描述
allocate(int capacity)开辟⼀个缓冲区, 并设置缓冲区的容量
put(byte b)将⼀个字节的数据存⼊缓冲区, position向后挪动⼀位。
put(byte[] arr)将⼀个字节数组的数据存⼊缓冲区, position向后挪动数组⻓度位
flip()将缓冲区切换成读模式。
get()获取⼀个字节的数据。
get(byte[] arr)将缓冲区中的数据读取到数组中。
mark()在缓冲区中添加⼀个标记, 将mark属性的值设置为当前的position的值。
reset()将属性position的值, 修改为mark记录的值。
rewind()倒回, 将position的值重置为0, 同时清空mark的标记的值。
clear()重置所有的属性为缓冲区刚刚被开辟时的状态

4.4 注意事项

  • 在向缓冲区中写数据的时候, 要注意:不要超出缓冲区的范围。如果超出范围 了,会出现BufferOverflowException 异常, 且本次put的所有数据都不会存⼊到缓冲区中

缓冲区, 其实有两种模式: 分别是读模式和写模式。
读模式: 就是从缓冲区中读取数据。
写模式:  就是将数据写⼊到缓冲区。
⼀个刚刚被开辟的缓冲区, 默认处于写模式

4.5 缓冲区的详解

其实, 缓冲区中, 并没有所谓的读模式和写模式。 其实所谓“读模式”和“写模式”, 只是逻辑上的区分。

⼀个处于“读模式”下的缓冲区, 依然可以写数据。

⼀个处理“写模式”下的缓冲区, 依然可以读取数据。

上述⽅法中, 基本所有的⽅法, 都是围绕着缓冲区中的⼏个属性进⾏的

5. Channel通道

5.1 通道的简介

通道Channel,就是⽂件和程序之间的连接。在NIO中,数据的传递,是由缓冲区实现的,通道本身并不负责数据的传递。

通道在 java.nio.channels 包中,常⻅的Channel⼦类:

  • 本地⽂件: FileChannel

  • ⽹络⽂件: SocketChannel, ServerSocketChannel, DatagramChannel

Channel类似于传统的流对象,但与传统的流对象有两个主要的区别:

  • Channel可以直接将我指定⽂件的部分或全部直接映射成Buffer

  • 程序不能直接访问Channel中的数据,包括读取,写⼊都不⾏.Channel只能与 Buffer进⾏交互

5.2 通道的打开方式

  1. 可以使⽤⽀持通道的类, getChannel()⽅法获取通道。

    1. 本地⽂件: FileInputStream、FileOutputStream

    2. ⽹络⽂件: Socket、ServerSocket、DatagramSocket

  2. 在NIO.2中,使⽤FileChannel.open()⽅法打开通道。

  3. 在NIO.2中,使⽤Files⼯具类newXXX()⽅法打开通道。

5.3 使用 FileChannel 读写数据

在使⽤FileChannel之前,必须先打开它。但是,我们⽆法直接打开⼀个 FileChannel,需要通过使⽤⼀个InputStream、OutputStream的getChannel()⽅法 来返回对应的Channe

6. JVM

6.1 类加载器 ClassLoader

类加载器, 负责加载class⽂件。 class⽂件在⽂件开头有特定的⽂件标示。

ClassLoader只负责class⽂件的加载, ⾄于它是否可以运⾏, 则由Execution Engine决定。

7.Properties

7.1简介

  • 概述

Properties也不是⼀个IO流, 是⼀个集合。 是Hashtable的⼦类。

使⽤Properties主要是为了描述程序中的属性列表⽂件。 有时候, 我们会将⼀些⽐ 较简单的项⽬的配置信息, 以 .properties 格式的⽂件进⾏存储。 可以使⽤ Properties对象读写 .properties ⽂件。

  • 注意

因为存储的是属性,属性本来就是以键值对的⽅式存储.这⾥的键和值都必须是字符串. 所以不需要考虑泛型

  • 为什么要在这⾥讲Properties?

因为他的使⽤与流紧密相关

  • Properties作⽤

1.是HashTable的⼦类,所以也是键值对形式,保存,操作更容易

2.默认键值都是字符串,所以不需要再考虑泛型

3.提供了⼀批好⽤的⽅法,⽅便使⽤(load(),store(),list()等)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值