把對象進行持久化(把對象存到本地)要用到對象流進行處理,在用對象流處理過程中,在寫對象和讀對象時候遇到了很多問題,分享一下。
我們處理對象數據的時候不可能只處理一個對象,在系統運行的時候,可能產生的對象數量是隨機的,對於向文件中寫入對象數據沒有什么影響,只需要向文件中寫入正確的對象即可,但是從文件中讀取對象操作的時候就需要我們進行判斷結束標志在哪里,什么時候結束讀操作,如果不能判斷在哪里結束,程序就會報錯,拋出異常。
Student類:
class Student implements Serializable{ public int id; public String name; public String sex; public Student(int id, String name, String sex) { this.id = id; this.name = name; this.sex = sex; } @Override public String toString() { return "Student{" + "id=" + id + ", name='" + name + '\'' + ", sex='" + sex + '\'' + '}'; } }
一、
在對一個對象進行處理的時候,我們不需要關心哪里結束,注意在最后要清空緩沖區和關閉資源
//讀取對象數據,保存到本地文件中 public static void read() { //聲明一個文件(創建文件) File file = null; //聲明文件輸出字節流 FileOutputStream fos = null; //聲明對象處理流 ObjectOutputStream oos = null; try { file = new File("E:\\a.txt"); fos = new FileOutputStream(file); oos = new ObjectOutputStream(fos); //向文件中寫入對象的數據 oos.writeObject(new Student(1002,"ll","女")); //清空緩沖區 oos.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { try { //關閉資源 fos.close(); oos.close(); } catch (IOException e) { e.printStackTrace(); } } }
//從文件中把對象數據讀取出來打印 public static void write() { File file = null; FileInputStream fis = null; ObjectInputStream ois = null; try { file = new File("E:\\a.txt"); fis = new FileInputStream(file); ois = new ObjectInputStream(fis); Student s = (Student)ois.readObject(); System.out.println(s); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { try { fis.close(); ois.close(); } catch (IOException e) { e.printStackTrace(); } } }
二、
當創建的對象數量不確定的時候,加入我們創建了兩個Student對象,並寫入文件中
public static void read() { //聲明一個文件(創建文件) File file = null; //聲明文件輸出字節流 FileOutputStream fos = null; //聲明對象處理流 ObjectOutputStream oos = null; try { file = new File("E:\\a.txt"); fos = new FileOutputStream(file); oos = new ObjectOutputStream(fos); oos.writeObject(new Student(1001,"llli","女")); oos.writeObject(new Student(1002,"ll","女")); //清空緩沖區 oos.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { try { //關閉資源 fos.close(); oos.close(); } catch (IOException e) { e.printStackTrace(); } } }
如果我們知道文件中有兩個對象的數據,我們可以讀取兩次,調用兩次讀取方法,分別讀取s和s1
public static void write() { File file = null; FileInputStream fis = null; ObjectInputStream ois = null; try { file = new File("E:\\a.txt"); fis = new FileInputStream(file); ois = new ObjectInputStream(fis); Student s = (Student)ois.readObject(); System.out.println(s); Student s1 = (Student)ois.readObject(); System.out.println(s1); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { try { fis.close(); ois.close(); } catch (IOException e) { e.printStackTrace(); } } }
但是往往我們不知道系統中保存了幾個對象,再說假如知道了對象的數量,這樣的代碼也是很不簡潔的,幾百個對象我們就要寫幾百個調用readObject()方法的語句,這時候我們想到了用while循環,當判斷文件中沒有對象數據的時候結束訪問,把上面調用兩次readObject()方法的語句換成下面這樣,放在while循環中
Object obj = null; while ((obj=ois.readObject()) != null) { System.out.println(obj); }
程序運行出錯了,程序可以讀取到第一個對象,但是當遇到第二個對象的時候,程序再向后執行不能判斷結束標志在哪里拋出EOFException
既然沒有結束標志我們在文件中加入一個結束標志,我們在之前的read()方法中,向文件中寫入對象的時候最后加上寫入一個null
oos.writeObject(new Student(1001,"llli","女")); oos.writeObject(new Student(1002,"ll","女")); oos.writeObject(null);
這樣程序在執行的時候,遇到這個null的時候就知道結束了,可以正確的操作