本文共 7451 字,大约阅读时间需要 24 分钟。
java.util.Properties
继承于 Hashtable
,来表示一个持久的属性集。它使用键值结构存储数据,每个键及其对应值都是一个字符串。该类也被许多Java类使用,比如获取系统属性时,System.getProperties
方法就是返回一个Properties
对象。加载文件中配置信息等等
public Properties()` :创建一个空的属性列表。
public Object setProperty(String key, String value) : 保存一对属性。 public String getProperty(String key) :使用此属性列表中指定的键搜索属性值。public SetstringPropertyNames() :所有键的名称的集合。
示例代码:
public static void main(String[] args) throws FileNotFoundException { // 创建属性集对象 Properties properties = new Properties(); // 添加键值对元素 properties.setProperty("filename", "a.txt"); properties.setProperty("length", "209385038"); properties.setProperty("location", "D:\\a.txt"); // 打印属性集对象 System.out.println(properties); // 通过键,获取属性值 System.out.println(properties.getProperty("filename")); System.out.println(properties.getProperty("length")); System.out.println(properties.getProperty("location")); // 遍历属性集,获取所有键的集合 Setstrings = properties.stringPropertyNames(); // 打印键值对 for (String key : strings ) { System.out.println(key+" -- "+properties.getProperty(key)); } }
输出结果:
{filename=a.txt, length=209385038, location=D:\a.txt}a.txt209385038D:\a.txtfilename -- a.txtlength -- 209385038location -- D:\a.txt
public void load(InputStream inStream): 从字节输入流中读取键值对。public void load(Reader reader): 从字节输入流中读取键值对。
参数中使用了字节输入流,通过流对象,可以关联到某文件上,这样就能够加载文本中的数据了。
加载代码演示:
public class Test3 { public static void main(String[] args) throws Exception{ /* 注意: 1.文本中的数据,必须是键值对形式,可以使用空格、等号、冒号等符号分隔。 2.如果配置文件中有中文,那么加载文件文件时,使用字符流,但是开发中一般配置文件中不要写中文 */ // 创建Properties对象 Properties pro = new Properties(); // 往pro对象中添加键值对 pro.setProperty("username", "root"); pro.setProperty("password", "123456"); pro.setProperty("url", "http://www.baidu.com"); // 把pro对象中的键值对写入到文件中 FileOutputStream fos = new FileOutputStream("db2.properties"); pro.store(fos,"itheima"); // 关闭流 fos.close(); }
加载(读取)配置文件中的数据
private static void method01() throws IOException { // 1.加载(读取)配置文件中的数据 // 创建Properties对象 Properties pro = new Properties(); // 调用load方法加载配置文件中的数据 //FileInputStream fis = new FileInputStream("a.txt"); FileInputStream fis = new FileInputStream("db2.properties"); pro.load(fis);// 把关联文件中的数据以键值对的形式存储到pro对象中 // 关闭流,释放资源 fis.close(); // 打印pro对象 System.out.println(pro); System.out.println("--------------------------------------------------"); // 注意事项: 如果配置文件中有中文 使用字符流 // 创建Properties对象 Properties pro2 = new Properties(); // 调用load方法加载配置文件中的数据 FileReader fr = new FileReader("a.txt"); pro2.load(fr);// 把关联文件中的数据以键值对的形式存储到pro对象中 // 关闭流,释放资源 fr.close(); // 打印pro对象 System.out.println(pro2); }}
缓冲流,也叫高效流,是对4个基本的FileXxx
流的增强,所以也是4个流,按照数据类型分类:
BufferedInputStream
,BufferedOutputStream
BufferedReader
,BufferedWriter
缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。
public BufferedInputStream(InputStream in) :创建一个 新的缓冲输入流。 public BufferedOutputStream(OutputStream out): 创建一个新的缓冲输出流。
构造举例,代码如下:
// 创建字节缓冲输入流BufferedInputStream bis = new BufferedInputStream(new FileInputStream("bis.txt"));// 创建字节缓冲输出流BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bos.txt"));
使用缓冲流读写一个字节拷贝文件
public class BufferedDemo { public static void main(String[] args) throws Exception { long start = System.currentTimeMillis(); // 创建字节输入流对象,关联数据源文件路径 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("B_test.exe")); // 创建字节输出流对象,关联目的地文件路径 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E_test.exe")); // 定义一个int类型的变量,用来存储读取到的字节数据 int len; // 循环读取 while ((len = bis.read()) != -1) { // 在循环中,写出数据 bos.write(len); } // 关闭流,释放资源 bos.close(); bis.close(); long end = System.currentTimeMillis(); System.out.println("总共需要:" + (end - start) + "毫秒");// 大约32秒 }}
使用缓冲流读写一个数组字节拷贝文件
public class BufferedDemo { public static void main(String[] args) throws FileNotFoundException { long start = System.currentTimeMillis(); // 创建字节输入流对象,关联数据源文件路径 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("B_test.exe")); // 创建字节输出流对象,关联目的地文件路径 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E_test.exe")); // 定义一个字节数组,用来存储读取到的字节数据 byte[] bys = new byte[8192]; // 定义一个int类型的变量,用来存储读取到的字节数据 int len; // 循环读取 while ((len = bis.read(bys)) != -1) { // 在循环中,写出数据 bos.write(bys,0,len); } // 关闭流,释放资源 bos.close(); bis.close(); long end = System.currentTimeMillis(); System.out.println("总共需要:" + (end - start) + "毫秒");// 大约4秒 }}
Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该对象的数据
、对象的类型
和对象中存储的属性
等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。
反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。对象的数据
、对象的类型
和对象中存储的数据
信息,都可以用来在内存中创建对象。看图理解序列化:
public ObjectOutputStream(OutputStream out): 创建一个指定OutputStream的ObjectOutputStream。
代码示例:
FileOutputStream fileOut = new FileOutputStream("employee.txt");ObjectOutputStream out = new ObjectOutputStream(fileOut);
一个对象要想序列化,必须满足两个条件:
java.io.Serializable
接口,Serializable
是一个标记接口public final void writeObject (Object obj) : 将指定的对象写出。
示例代码:
public class Test { public static void main(String[] args)throws Exception { // 创建Student对象 Student s = new Student("张三", 18); // 需求:将s对象写入到 C:\\Users\\86183\\Desktop\\ser.txt 文件中 // 创建序列化流对象,关联目的地文件路径 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\86183\\Desktop\\ser.txt")); // 写出对象 oos.writeObject(s); // 关闭流,释放资源 oos.close(); }}
对象序列化包括如下步骤:
1) 创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;2) 通过对象输出流的writeObject()方法写对象。
ObjectInputStream反序列化流,将之前使用ObjectOutputStream序列化的原始数据恢复为对象。
public ObjectInputStream(InputStream in) : 创建一个指定InputStream的ObjectInputStream
如果能找到一个对象的class文件,我们可以进行反序列化操作,调用ObjectInputStream
读取对象的方法:
public final Object readObject () : 读取一个对象。
示例代码:
public class Test { public static void main(String[] args) throws Exception{ // 反序列化:读取之前序列化的对象 // 1.创建反序列化流对象,关联数据源文件路径 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\Users\86183\Desktop\ser.txt")); // 2.读取一个对象 Object obj = ois.readObject(); System.out.println(obj); // 3.关闭流,释放资源 ois.close(); }}
对象反序列化的步骤如下:
1) 创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;2) 通过对象输入流的readObject()方法读取对象。
我们可以看到,先通过输入流创建一个文件,再调用ObjectOutputStream
类的 writeObject方法
`,把序列化的数据写入该文件;
然后调用ObjectInputStream
类的readObject方法
反序列化数据并打印数据内容
对于JVM可以反序列化对象,它必须是能够找到class文件的类。如果找不到该类的class文件,则抛出一个 ClassNotFoundException
异常。
另外,当JVM反序列化对象时,能找到class文件,但是class文件在序列化对象之后发生了修改,那么反序列化操作也会失败,抛出一个InvalidClassException
异常。发生这个异常的原因如下:
Serializable
接口给需要序列化的类,提供了一个序列版本号。serialVersionUID
该版本号的目的在于验证序列化的对象和对应类是否版本匹配。
转载地址:http://dxxzz.baihongyu.com/