IO流小结(二)
承接上文,繼續小小總結一下IO流。
上文主要總結了一下IO流中的基本流,下面主要總結一下IO流中的包裝流/高級流
現在假設我想我文本中輸入小數,該怎么辦呢?用上面的方式無效。那么現在介紹一下:
包裝流/高級流:
(1)DataInputStream/DataOutputStream:數據流
(2)BufferedInputStream/BufferedOutputStream:緩沖流
(1)我們用DataInputStream/DataOutputStream:解決上述問題
我們還是看下面一段代碼:主要完成向d:/c.txt文本中寫入小數3.14和漢字“中國”,如果d盤沒有c.txt則先創建文件在寫入,之后從該文本中讀出相應數據
import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class TestDISDOS { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream(new File("d:\\c.txt")); DataOutputStream dos = new DataOutputStream(fos); dos.writeDouble(3.14); dos.writeUTF("中國"); FileInputStream fis = new FileInputStream(new File("d:\\c.txt")); DataInputStream dis = new DataInputStream(fis); double d = dis.readDouble(); String s = dis.readUTF(); System.out.println(d); System.out.println(s); // 如何快速寫小數 // BufferedOutputStream/DataOutputStream/FileOutputStream在上面已經陳述過該等價關系 DataOutputStream out = new DataOutputStream( new BufferedOutputStream( new FileOutputStream(new File("d:\\c.txt")))); out.writeDouble(3.1415); // 對于包裝流,關閉時候只關閉外層流就可以了,外層流中有對內層流的關閉。 dos.close(); dis.close(); out.close(); } }(2)現在我想將一個文件復制一個副本,用上面方法不能說不能實現,只是比較麻煩,效率也很低,那該怎么辦呢?于是引出了包裝流中的BufferedInputStream/BufferedOutputStream:
還是以代碼的形式呈現:完成將d:/src.rar復制一份并且以文件名為desc.rar存放
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class TestBISBOS { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream(new File("d:\\src.rar")); BufferedInputStream bis = new BufferedInputStream(fis); FileOutputStream fos = new FileOutputStream(new File("d:\\dest.rar")); BufferedOutputStream bos = new BufferedOutputStream(fos); int i = 0; //bis.read()==-1代表已經讀到末尾 while((i=bis.read())!=-1){ bos.write(i); // flush不要放在循環中,不然沒意義,相當于一個字節一個字節的寫。 // bos.flush();// 沖刷緩沖區,強制將緩沖區中的內容寫入文件 } // 如果緩沖區滿了,自動寫入文件 bos.flush();// 沖刷緩沖區,強制將緩沖區中的內容寫入文件 bos.close();// close關閉之前,先flush。 } }現在又有新問題了。我想存入的不僅僅是簡單的字節或者double類型的數據,而是一個Person類對象該如何是好呢?應運而生的產生了對象流(1)ObjectOutputStream/ObjectInputStream
有一下代碼先創建一個Person類有姓名和年齡兩個屬性,注意這里用到了對象序列化。
對象序列化:就是把對象變成二進制或文本
Person類
import java.io.Serializable; public class Person implements Serializable{//這里需要實現序列化接口 private String name; private int age; public Person() { super(); } public String getName() { return name; } public Person(String name, int age) { super(); this.name = name; this.age = age; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } }還有一個測試類TestOISOOS類
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import practice.Person; public class TestOISOOS { public static void main(String[] args) throws Exception { File file = new File("d:\\person.data"); // 輸出流新建文件 FileOutputStream fos = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(fos); //創建Person對象p1 Person p1 = new Person("zhangfei",23); //對象寫入現在可以查看d盤下多了一個peison.data文件 oos.writeObject(p1);//對象序列化 FileInputStream fis = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(fis); //對象讀出,用Person對象接受 Person p2 = (Person) ois.readObject();//對象反序列化 System.out.println(p2); ois.close(); oos.close(); } }輸出結果:
Person?[name=zhangfei,?age=23]
(2)上面代碼用到了對象序列化,但只是單個對象的序列化,那么如何實現多個對象的序列化呢?請看下面代碼還是要借助Person類
import java.io.EOFException; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class TestSer { public static void main(String[] args) throws Exception { Person p1 = new Person("zhangfei",20); Person p2 = new Person("guanyu",30); File file = new File("d:\\person.data"); // 輸出流新建文件 FileOutputStream fos = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(p1);// 對象序列化 oos.writeObject(p2); FileInputStream fis = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(fis); // 不建議使用這種方式序列化多個對象,while中死循環,通過break跳出 while(true){ try { Person p = (Person) ois.readObject();// 對象反序列化 System.out.println(p); } catch (EOFException e) { System.out.println("讀到了文件的末尾"); break; } }輸出結果:
Person?[name=zhangfei,age=20]
Person?[name=guanyu,age=30]
讀到了文件的末尾
對于多個對象的序列化,前面也提到了不建議使用上述方法,那么我們還可以借助集合實現多個對象的序列化。請看代碼。還是同上需要借助Person類,這里不再寫Person類了
import java.io.*; import java.util.*; /** * 利用集合完成多個對象的序列化,推薦使用這種方式。 */ public class TestSerCol { public static void main(String[] args) throws Exception { File file = new File("d:\\person.data"); FileOutputStream fos = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(fos); List<Person> list = new ArrayList<Person>(); Person p1 = new Person("zhangfei",20); Person p2 = new Person("guanyu",30); list.add(p1); list.add(p2); // 序列化整個集合 oos.writeObject(list); FileInputStream fis = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(fis); List<Person> perList = (List<Person>) ois.readObject(); for(Person p : perList){ System.out.println(p); } oos.close(); ois.close(); } }輸出結果:
Person?[name=zhangfei,age=20]
Person?[name=guanyu,age=30]
哎,終于結束了
?
?
?
?
轉載于:https://blog.51cto.com/champagne/1260025
總結
- 上一篇: linux配置dhcp中继服务
- 下一篇: iPhone屏幕做一个最上层全屏幕的la