I/O的一些应用补充

1. properties的应用

Properties 继承自HashTable类,是一个持久的属性集,本质也是键值对存储,可以保存在流中或从流中加载。 

1.1 特点:

1、Hashtable的子类,map集合中的方法都可以用。

2、该集合没有泛型,键值都是字符串。

3、它是一个可以持久化的属性集。键值可以存储到集合中,也可以存储到持久化的设备(硬盘、U盘、光盘)上。键值的来源也可以是持久化的设备。

4、有和流技术相结合的方法。

1.2 构造器:不带参构造器和给定默认值的构造器

Properties()

Creates an empty property list with no default values.

Properties(Properties defaults)

Creates an empty property list with the specified defaults.

 1.3 常用方法

String getProperty(String key)

Searches for the property with the specified key in this property list.

void load(InputStream inStream)

Reads a property list (key and element pairs) from the input byte stream.

void load(Reader reader)

Reads a property list (key and element pairs) from the input character stream in a simple line-oriented format.

void loadFromXML(InputStream in)

Loads all of the properties represented by the XML document on the specified input stream into this properties table.

Object setProperty(String key, String value)

Calls the Hashtable method put.

void store(OutputStream out, String comments)

Writes this property list (key and element pairs) in this Properties table to the output stream in a format suitable for loading into a Properties table using the load(InputStream) method.

void store(Writer writer, String comments)

Writes this property list (key and element pairs) in this Properties table to the output character stream in a format suitable for using the load(Reader) method.

1.4 程序示例

将properties集合写入.properties文件

    /**   
     * @Title: storePropertiesToStream   
     * @Description: 将properties集合写入.properties文件   
     * @param:       
     * @return: void      
     * @throws   
     */  
    public static void storePropertiesToStream() {
        Properties props = new Properties();
        props.setProperty("name", "xxxxiao");
        props.setProperty("password", "nicai");
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(new File("d:\\test\\my.properties"));
            props.store(fos, null);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fos.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

从.properties文件中读取属性到集合中

    /**   
     * @Title: loadPropertiesFromStream   
     * @Description: 从.properties文件中读取properties键值对
     * @param:       
     * @return: void      
     * @throws   
     */  
    public static void loadPropertiesFromStream() {
        Properties props = new Properties();
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(new File("d:\\test\\my.properties"));
            props.load(fis);
            System.out.println(props);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fis.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

2. 对象的序列化

IO流中有一种用于从流中存取对象的流,ObjectOutputStream——对象序列化流,ObjectInputStream——对象反序列化流。

2.1 ObjectOutputStream

用于向流中写入对象,常用方法:

void writeObject(Object obj)

Write the specified object to the ObjectOutputStream.

2.2 ObjectInputStream

用于从流中读取对象,常用方法:

Object readObject()

Read an object from the ObjectInputStream.

2.3 对象序列化和反序列化的例子

一个对象要序列化,首先要实现可序列化接口Serializable.

package com.ch25.seri;

import java.io.Serializable;

public class Person implements Serializable {
    /**
     * @Fields serialVersionUID : 自定义序列号,防止因为改写类而导致.class文件改变,序列号改变导致无法反序列化  
     */
    private static final long serialVersionUID = 12432453L;
    private String name;
    private int age;
    
    public Person() {
        super();
    }
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getPassword() {
        return age;
    }
    public void setPassword(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
}

序列化和反序列化:

/**   
     * @Title: writeObject   
     * @Description: 利用ObjectOutputStream序列化   
     * @param: @param obj      
     * @return: void      
     * @throws   
     */  
    public static void writeObject(Object obj) {
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream("d:\\test\\Person.object"));
            oos.writeObject(obj);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                oos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    /**   
     * @Title: readObject   
     * @Description: 利用ObjectInputStream反序列化   
     * @param:       
     * @return: void      
     * @throws   
     */  
    public static void readObject() {
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("d:\\test\\Person.object"));
            Object obj = ois.readObject();
            System.out.println(obj);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

main方法:

public static void main(String[] args) {
        Person person = new Person("Tom", 13);
        writeObject(person);
        
        readObject();
        
    }

先进行序列化,在d:\test\Person.object文件中就写入了序列化后的对象,然后再将该文件中的内容通过字节流传递给反序列化流,重新得到对象obj,并打印到控制台。

注意:

1. 被序列化的对象必须实现Serializable接口

2. 该接口给序列化的类提供了一个序列版本号serialVersionUID,用于验证序列化的对象和对应的类是否匹配。这里需要自己指定一个default序列号——private static final long serialVersionUID = 12432453L;  限定修饰符不可以改变。这样即使对象序列化后又修改了源代码,编译后生产的.class文件变化了,也不会改变序列号,对象可以正常序列化和反序列化。

3. 不会被序列化的属性:transient修饰的瞬态属性,以及static静态属性(因为静态不属于对象)

3. 打印流

打印流分为字节打印流PrintStream和字符打印流PrintWriter。有print(String str)和println(String str)方法。

常用的System.out.println()就是打印流,打开源码可以看到System类中的静态属性 out 就是打印流:

public final static PrintStream out = null;

PrintStream构造器可以接受的参数类型有:File,String文件名,OutputStream任何子类

PrintWriter构造器可以接受的参数类型有:File,String文件名,Writer任何子类,OutputStream任何子类

public static void main(String[] args) {
        PrintWriter pw = null;
        PrintStream ps = null;
        try {
            pw = new PrintWriter("d:\\test\\printWriter.txt");
            pw.print("克罗地亚");
            pw.println("lolololololol");
            pw.flush();
            ps = new PrintStream("d:\\test\\printStream.txt");
            ps.println(new char[] {'a','b','c'}); //abc
            ps.println(100); //100
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            pw.close();
            ps.close();
        }
    }

注:以下三种构造器有自动刷新功能,只需要将第二个参数置为true,打印流就会自动flush(),无需手动调用

PrintStream(OutputStream out, boolean autoFlush)

Creates a new print stream.

PrintWriter(OutputStream out, boolean autoFlush)

Creates a new PrintWriter from an existing OutputStream.

PrintWriter(Writer out, boolean autoFlush)

Creates a new PrintWriter.

打印流也可以实现文件复制,例如用PrintWriter代替BufferedWriter复制文本文件,使用起来比较方便:

/**   
     * @Title: copyByPrintWriter   
     * @Description: 通过打印流复制文本文件   
     * @param:       
     * @return: void      
     * @throws   
     */  
    public static void copyByPrintStream() {
        // bufferedReader 读取src文件
        BufferedReader br = null;
        // 写入不采用bufferedWriter,使用printWriter写入desc文件
        PrintWriter pw = null;
        try {
            br = new BufferedReader(new FileReader("d:\\test\\from.txt"));
            pw = new PrintWriter(new FileWriter("d:\\test\\desc.txt"), true);
            String line = null;
            while ((line = br.readLine()) != null) {
                pw.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            pw.close();
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

4. 第三方工具类commons-io.jar

该工具包提供了多种非常实用的封装好的I/O操作,可以处理文件名,移动、读取文件,复制文件、文件夹等,具体参考api文档。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章