Java基础知识点汇总 六 Buffer缓冲区

一、简述

        在使用传统的I/O流API时,如InputStream和OutputStream,以及Reader和Writer联合使用时,常常把字节流中的数据放入byte[]字节数组中,或把字符流中的数据放入char[]字符数组中,也可以从byte[]或char[]数组中获取数据来实现功能上的需求,但由于在Java语言中对array数组自身进行操作的API非常少,常用的操作仅仅是length属性和下标[x]了,在JDK中也没有提供更加方便操作数组中数据的API,如果对数组中的数据进行高级处理,需要程序员自己写代码进行实现,处理的方式是比较原始的,这个问题可以使用NIO技术中的缓冲区Buffer类来解决,它提供了很多工具方法,大大提高了程序开发的效率。

        从Buffer类的Java文档中可以发现,Buffer类是一个抽象类,它具有7个直接子类,分别是ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer、ShortBuffer,也就是缓冲区中存储的数据类型并不像普通I/O流只能存储byte或char数据类型,Buffer类能存储的数据类型是多样的。

        类java.lang.StringBuffer是在lang包下的,而在nio包下并没有提供java.nio.StringBuffer缓冲区,在NIO中存储字符的缓冲区可以使用CharBuffer类。NIO中的Buffer是一个用于存储基本数据类型值的容器,它以类似于数组有序的方式来存储和组织数据。每个基本数据类型(除去boolean)都有一个子类与之对应。

二、StringBuffer

        StringBuffer是线程安全的,有加锁开销,效率略低。StringBuilder非线程安全,不用加锁,效率更高。

        1、适合使用String类的场景:在字符串不经常变化的场景中可以使用String类,例如常量的声明、少量的变量运算。

        2、使用StringBuffer类的场景:在频繁进行字符串运算(如拼接、替换、删除等),并且运行在多线程环境中,则可以考虑使用StringBuffer,例如XML解析、HTTP参数解析和封装。 

        3、使用StringBuilder类的场景:在频繁进行字符串运算(如拼接、替换、和删除等),并且运行在单线程的环境中,则可以考虑使用StringBuilder,如SQL语句的拼装、JSON封装等。

三、缓冲区

        缓冲区在java.nio包中定义。它定义了所有缓冲区共有的核心功能:限制、容量和当前位置。

        Java NIO 缓冲区用于与 NIO 通道交互。它是我们可以写入数据的内存块,稍后我们可以再次读取这些数据。内存块用 NIO 缓冲区对象包装,它提供了更简单的方法来处理内存块。

        缓冲是一种 I/O 性能增强技术。使用这些的优点是通过在内存中将较小的输出组合在一起来减少 I/O 请求的数量。每个输出操作都指向内存中称为缓冲区的区域,该缓冲区大到足以容纳许多输出操作的数据。使用缓冲可以大大提高应用程序的性能。与访问计算机内存中数据的速度相比,典型的 I/O 操作非常慢。

        由于ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer和ShortBuffer是抽象类,因此wrap()就相当于创建这些缓冲区的工厂方法。

        ByteBuffer类缓冲区的技术原理就是使用byte[]数组进行数据的保存,在后续使用指定的API来操作这个数组以达到操作缓冲区的目的,示例代码如图1-9所示。

        从源代码中可以了解到,缓冲区存储的数据还是存储在byte[]字节数组中。使用缓冲区与使用byte[]字节数组的优点在于缓冲区将存储数据的byte[]字节数组内容与相关的信息整合在1个Buffer类中,将数据与缓冲区中的信息进行了整合,并进行了封装,这样便于获得相关的信息及处理数据。

四、基本缓冲区使用

         使用 aBuffer读取和写入数据通常遵循以下 4 步小过程:

        将数据写入缓冲区

        调用buffer.flip()

        从 Buffer 中读取数据

        调用buffer.clear()或buffer.compact()

        当您将数据写入缓冲区时,缓冲区会跟踪您写入的数据量。一旦需要读取数据,就需要使用flip()方法调用将缓冲区从写入模式切换到读取模式。在读取模式下,缓冲区允许您读取写入缓冲区的所有数据。

        读取所有数据后,您需要清除缓冲区,使其准备好再次写入。您可以通过两种方式执行此操作:调用clear()或调用 compact(). 该clear()方法清除整个缓冲区。该compact() 方法仅清除您已读取的数据。任何未读数据都被移动到缓冲区的开头,数据将在未读数据之后写入缓冲区。

猜你喜欢

转载自blog.csdn.net/bashendixie5/article/details/127210703