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的主要内容,如果未能解决你的问题,请参考以下文章