序列化流與反序列化流,列印流,工具類commons-IO
1序列化流與反序列化流
用於從流中讀取物件的操作流 ObjectInputStream 稱為 反序列化流
用於向流中寫入物件的操作流 ObjectOutputStream 稱為 序列化流
特點:用於操作物件。可以將物件寫入到檔案中,也可以從檔案中讀取物件。
1.1物件序列化流ObjectOutputStream
例:
import java.io.Serializable; public class Person implements Serializable{ 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 getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } }
import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; public class Test { public static void main(String[] args) throws IOException, ClassNotFoundException { method01(); } // 序列化 public static void method01() throws IOException { Person p = new Person("zhangsan", 18); // 明確目的地 FileOutputStream fos = new FileOutputStream("E:\\zyx\\java\\Person.txt"); // 建立序列化流 ObjectOutputStream oos = new ObjectOutputStream(fos); // 會自動關閉fos // 向檔案中寫入物件 oos.writeObject(p); oos.close(); } }
1.2序列化介面
如果類都可以序列化,不安全。所以必須實現介面,才允許序列化:
標記型介面,沒有方法,不用重寫,沒有實際意義。
加上後再執行:
1.3對象反序列化流ObjectInputStream
例:
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class Test { public static void main(String[] args) throws IOException, ClassNotFoundException { method02(); } // 序列化 public static void method01() throws IOException { Person p = new Person("zhangsan", 18); // 明確目的地 FileOutputStream fos = new FileOutputStream("E:\\zyx\\java\\Person.txt"); // 建立序列化流 ObjectOutputStream oos = new ObjectOutputStream(fos); // 會自動關閉fos // 向檔案中寫入物件 oos.writeObject(p); oos.close(); } // 反序列化 public static void method02() throws ClassNotFoundException, IOException { // 明確資料來源 FileInputStream fis = new FileInputStream("E:\\zyx\\java\\Person.txt"); // 建立反序列化流 ObjectInputStream ois = new ObjectInputStream(fis); Object obj = ois.readObject(); Person p = (Person) obj; // 強轉 System.out.println(p); ois.close(); } }
說明:
1)readObject();返回值型別是Object
所以用Object接收,再強轉
2)ClassNotFoundException這個異常
如果bin中的Person.class丟失,那麼就會報這個異常
如果把age加上static
執行method01(),再執行method02(),
這說明序列化和反序列化的只是物件,靜態後的屬性因為不屬於物件了,所以不會被序列化。
還可以加上瞬態關鍵字transient
1.4瞬態關鍵字transient
執行method01(),再執行method02(),
1.5序列版本號
把Person任意改一下,直接反序列化:
結果為:序列化衝突異常
圖說明:
所以序列化後不要再改動Person了。
解決辦法:給Person加一個序列化號:(可以直接點出來)
這個long值可以任意改,
加上後,再序列化,然後修改Person,再反序列化,就不會報異常了。
2列印流
只是輸出流
根據流的分類:
位元組列印流 PrintStream
字元列印流 PrintWriter
方法:
void print(String str): 輸出任意型別的資料,
void println(String str): 輸出任意型別的資料,自動寫入換行操作
可以用write方法,但是走碼錶,而這兩個是原樣輸出
2.1PrintStream
例:
import java.io.IOException; import java.io.PrintStream; public class Test { public static void main(String[] args) throws IOException, ClassNotFoundException { PrintStream ps=new PrintStream("E:\\zyx\\java\\print.txt"); ps.print(100); ps.println("你好"); ps.println("換行"); ps.write(100); ps.close(); } }
說明:
print()原樣輸出
println()可以換行
write()走碼錶
2.2續寫
傳一個FileOutputStream物件:
import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; public class Test { public static void main(String[] args) throws IOException, ClassNotFoundException { FileOutputStream fos=new FileOutputStream("E:\\zyx\\java\\print.txt",true); PrintStream ps=new PrintStream(fos); ps.print(100); ps.println("你好"); ps.println("換行"); ps.write(100); ps.close(); } }
2.3 PrintWriter
例:
import java.io.IOException; import java.io.PrintWriter; public class Test { public static void main(String[] args) throws IOException, ClassNotFoundException { PrintWriter pw=new PrintWriter("E:\\zyx\\java\\print.txt"); pw.println("你好"); pw.println("java"); pw.flush(); pw.close(); } }
2.4自動重新整理
import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; public class Test { public static void main(String[] args) throws IOException, ClassNotFoundException { // 位元組輸出流明確目的地 FileOutputStream fos = new FileOutputStream("E:\\zyx\\java\\print.txt"); // 建立自動重新整理的字元列印流 PrintWriter pw = new PrintWriter(fos, true); pw.println("你好"); pw.println("java"); pw.close(); } }
2.5複製
import java.io.BufferedReader; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; public class CopyTest { public static void main(String[] args) throws IOException { copy(); } public static void copy() throws IOException{ //明確資料來源 FileReader fr=new FileReader("E:\\zyx\\java\\print.txt"); BufferedReader br=new BufferedReader(fr); //明確目的地 FileWriter fw=new FileWriter("E:\\zyx\\java\\a\\print.txt"); PrintWriter pw=new PrintWriter(fw,true); //自動重新整理 String line=""; while((line=br.readLine())!=null){ pw.println(line); } br.close(); pw.close(); } }
用列印流複製不用重新整理和換行了
列印流總結:
1)只有輸出目的地
2)不會拋IO異常
3 工具類commons-IO
3.1匯入classpath
加入classpath的第三方jar包內的class檔案才能在專案中使用
建立lib資料夾
將commons-io.jar拷貝到lib資料夾
右鍵點選commons-io.jar,Build Path→Add to Build Path
3.2 FilenameUtils
用來處理檔名的,可以輕鬆解決不同作業系統檔名稱規範不同的問題
常用方法:
1)getExtension(String path):獲取檔案的副檔名;
2)getName(String filename):獲取檔名;
3)isExtension(String fileName,String ext):判斷fileName是否是ext字尾名;
例:
import java.io.IOException; import org.apache.commons.io.FilenameUtils; public class Test { public static void main(String[] args) throws IOException, ClassNotFoundException { // 獲取副檔名 String ext = FilenameUtils.getExtension("E:\\zyx\\java\\demo.txt"); System.out.println(ext); // 獲取檔名 String filename = FilenameUtils.getName("E:\\zyx\\java\\demo.txt"); System.out.println(filename); // 判斷是否是java檔案 boolean flag = FilenameUtils.isExtension("E:\\zyx\\java\\demo.txt", "java"); System.out.println(flag); } }
3.3 FileUtils
常用方法:
1)readFileToString(File file):讀取檔案內容,並返回一個String;
import java.io.File; import java.io.IOException; import org.apache.commons.io.FileUtils; public class Test { public static void main(String[] args) throws IOException, ClassNotFoundException { File file=new File("E:\\zyx\\java\\print.txt"); String content=FileUtils.readFileToString(file); System.out.println(content); } }
2)writeStringToFile(File file,String content):將內容content寫入到file中;
import java.io.File; import java.io.IOException; import org.apache.commons.io.FileUtils; public class Test { public static void main(String[] args) throws IOException, ClassNotFoundException { File file=new File("E:\\zyx\\java\\print.txt"); FileUtils.writeStringToFile(file, "你好"); } }
3)copyDirectoryToDirectory(File srcDir,File destDir); 資料夾複製
import java.io.File; import java.io.IOException; import org.apache.commons.io.FileUtils; public class Test { public static void main(String[] args) throws IOException, ClassNotFoundException { // 資料來源 File file = new File("E:\\zyx\\java\\b"); // 目的地 File file2 = new File("E:\\zyx\\java\\e"); // 複製 FileUtils.copyDirectoryToDirectory(file, file2); } }
4)copyFile(File srcFile,File destFile); 檔案複製
import java.io.File; import java.io.IOException; import org.apache.commons.io.FileUtils; public class Test { public static void main(String[] args) throws IOException, ClassNotFoundException { // 資料來源 File file = new File("E:\\zyx\\java\\eclipse.zip"); // 目的地 File file2 = new File("E:\\zyx\\java\\f\\eclipse.zip"); // 複製 long start=System.currentTimeMillis(); FileUtils.copyFile(file, file2); long end=System.currentTimeMillis(); System.out.println(end-start); } }
練習:用常規方法複製資料夾(及檔案)