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文檔。

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