IO——Properties和NIO

Posted dch-21

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IO——Properties和NIO相关的知识,希望对你有一定的参考价值。

Properties

Properties也不是一个IO流,是一个集合。是Hashtable的子类。使用Properties主要是为了描述程序中的属性列表文件。有时候,我们会将一些比较简单的项目的配置信息,以.properties格式的文件进行存储。可以使用Properties对象读写.properties 文件。

import java.io.*;
import java.util.Properties;

public class Test {
    public static void main(String[] args) {
        // 1. 实例化一个Properties对象
        Properties properties = new Properties();

        // 2. 加载一个 .properties 文件中的数据
        try {
            properties.load(new FileReader("filemy.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 3. 遍历
        System.out.println(properties);
        // 4. 键值对的增删改查
        //    由于这个类是Map的实现类,因此在Map集合中定义的所有的方法,它都有。
        //    但是,对于Properties类的来说,增删改查基本上不用从Map中继承到的方法。
        //    因为,从Map集合中继承下来的方法,键和值都是Object类型的。
        // 4.1. 可以在集合中新增一个键值对,也可以修改集合中的存在的键值对。
        properties.setProperty("userlevel","12");
        properties.setProperty("password","ABCDEF");
        // 4.2. 通过键,获取值
        String level = properties.getProperty("userlevel");
        String id = properties.getProperty("userid", "123");
        System.out.println(properties);
        // 5. 将内存中的数据,同步到文件中
        try{
            
            properties.store(new FileWriter("filemy.properties"),
                    "hello");
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

技术图片

NIO

NIO:New IO。Non-Blocking IO(非阻塞IO)。
NIO是JDK1.4的时候出现了一个新的IO,用来替代传统的IO流。NIO与IO有着相同的功能,但是操作的方法不同。NIO是基于通道(Channel),面向缓冲区(Buffer)的。在JDK1.7的时候,为NIO添加了一些新的特定。被称为NIO.2

和传统的IO的区别

  • IO是面向流的,NIO是面向缓冲区的。
  • IO是阻塞型的,NIO是非阻塞型的。

Buffer缓冲区

其实是一个用来存储基本数据类型的一个容器,类似于一个数组。缓冲区,可以按照存储的数据类型不同,将缓冲区分为:
ByteBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer、CharBuffer
但是,要注意,并没有BooleanBuffer!这些缓冲区,虽然是不同的类,但是他们拥有的相同的属性和方法。因为他们都继承自相同的父类Buffer。

Buffer的几个属性

  • capacity: 容量。代表一个缓冲区的最大的容量,缓冲区一旦开辟完成,将无法修改。
  • limit: 限制。表示缓冲区中有多少数据可以操作。
  • position: 位置。表示当前要操作缓冲区中的哪一个下标的数据。
  • mark: 标记。在缓冲区中设计一个标记,配合 reset() 方法使用,修改position的值。

mark <= position <= limit <= capacity

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() 重置所有的属性为缓冲区刚刚被开辟时的状态。
  • 注意事项
    • 在向缓冲区中写数据的时候,要注意:不要超出缓冲区的范围。如果超出范围了,会出现BufferOverflowException异常,且本次put的所有数据都不会存入到缓冲区中。

缓冲区,其实有两种模式:分别是读模式和写模式。

读模式: 就是从缓冲区中读取数据。

写模式: 就是将数据写入到缓冲区。

一个刚刚被开辟的缓冲区,默认处于写模式。

缓冲区的详解

其实,缓冲区中,并没有所谓的读模式和写模式。其实所谓“读模式”和“写模式”,只是逻辑上的区分。一个处于“读模式”下的缓冲区,依然可以写数据。一个处理“写模式”下的缓冲区,依然可以读取数据。上述方法中,基本所有的方法,都是围绕着缓冲区中的几个属性进行的。

import java.io.*;
import java.nio.ByteBuffer;
import java.util.Properties;

public class Test {
    public static void main(String[] args) {
        //开辟一个capacity为10的缓冲区
        //此时capacity为10,limit为10,position为0,mark为-1
        ByteBuffer buffer=ByteBuffer.allocate(10);
        System.out.println(buffer.capacity()+","+buffer.limit()+","+buffer.position());
        //添加数据,此时capacity为10,limit为10,position为5
        buffer.put("hello".getBytes());
        System.out.println(buffer.capacity()+","+buffer.limit()+","+buffer.position());
        //切换到“读”模式
        buffer.flip();
        //capacity:10,limit:5,position:0
        System.out.println(buffer.capacity()+","+buffer.limit()+","+buffer.position());
        //从缓冲区中读数据
        byte[]arr=new byte[buffer.limit()];
        buffer.get(arr);
        //hello
        System.out.println(new String(arr));
        //capacity:10,limit:5,position:5
        System.out.println(buffer.capacity()+","+buffer.limit()+","+buffer.position());
        //继续写数据wor会报错BufferOverflowException,此时的position=limit=5。position<=limit<=capacity
//        buffer.put("wor".getBytes());
//        System.out.println();
        buffer.flip();
        //capacity:10,limit:5,position:0
        System.out.println(buffer.capacity()+","+buffer.limit()+","+buffer.position());
        //写入wor字节数组
        buffer.put("wor".getBytes());
        //capacity:10,limit:5,position:3
        System.out.println(buffer.capacity()+","+buffer.limit()+","+buffer.position());
        //重置position,如若不重置就会出现BufferUnderflowException,posistion是3+5=8>5超出了limit
        buffer.rewind();
        System.out.println(buffer.capacity()+","+buffer.limit()+","+buffer.position());
        byte[]arr1=new byte[buffer.limit()];
        buffer.get(arr1);
        //worlo
        System.out.println(new String(arr1));
        //capacity:10,limit:5,position:5
        System.out.println(buffer.capacity()+","+buffer.limit()+","+buffer.position());
        buffer.clear();
        ////此时capacity为10,limit为10,position为0,mark为-1
        System.out.println(buffer.capacity()+","+buffer.limit()+","+buffer.position());
        //读取数据
        byte[] arr2= new byte[7];
        buffer.get(arr2);
        //worllo  最后面会有两个空格
        System.out.println(new String(arr2));
        //capacity:10,limit:10,position:7
        System.out.println(buffer.capacity()+","+buffer.limit()+","+buffer.position());
    }
}

直接缓冲区

非直接缓冲区,是在JVM中开辟的空间。allocate(int capacity)
直接缓冲区,是直接在物理内存上开辟的空间。allocateDirect(int capacity)

对于一个已经存在的缓冲区,可以使用isDirect() 方法,判断是否是直接缓冲区。这个方法的返回值类型是boolean类型的,如果是true, 就表示是一个直接缓冲区。如果是false,就表示不是一个直接缓冲区。

以上是关于IO——Properties和NIO的主要内容,如果未能解决你的问题,请参考以下文章

java----IO和NIO的区别

Java NIO系列教程 Java NIO与IO

Java NIO和IO的区别(转)

Java IO之NIO原理解析以及代码解析

Java NIO和IO的主要差别

Java NIO 与 IO