1. 程式人生 > >序列化流與反序列化流,列印流,工具類commons-IO

序列化流與反序列化流,列印流,工具類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();
	}
}

 

說明:

1readObject();返回值型別是Object

所以用Object接收,再強轉

2ClassNotFoundException這個異常

如果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.jarBuild PathAdd to Build Path

 

3.2 FilenameUtils

用來處理檔名的,可以輕鬆解決不同作業系統檔名稱規範不同的問題

常用方法:

1getExtension(String path):獲取檔案的副檔名;

2getName(String filename):獲取檔名;

3isExtension(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 fileString 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);
	}
}

 

練習:用常規方法複製資料夾(及檔案)