黑馬程式設計師—物件的序列化和字元編碼以及21天視訊中其他知識總結
---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS開發</a>、<a href="http://edu.csdn.net"target="blank">.Net培訓</a>、期待與您交流! ----------------------
一、 物件的序列化
Serializable
類通過實現 java.io.Serializable 介面以啟用其序列化功能。未實現此介面的類將無法使其任何狀態序列化或反序列化。可序列化類的所有子型別本身都是可序列化的。序列化介面沒有方法或欄位,僅用於標識可序列化的語義
序列化執行時使用一個稱為 serialVersionUID 的版本號與每個可序列化類相關聯,該序列號在反序列化過程中用於驗證序列化物件的傳送者和接收者是否為該物件載入了與序列化相容的類。
下面是Person實現序列化的例項:
class Person implements Serializable
{
//序列化Person類,使其在持久化是唯一
staticfinallongserialVersionUID = 42L;
String name;
intage;
//contry的值是唯一的,例項化該類時無論contry引數被賦值為任何值時
//contry的值是cn一直不會被改變
static String
public Person(String name,int age,String contry)
{
this.name = name;
this.age = age;
this.contry = contry;
}
public String toString()
{
returnname+"--"+age+"--"+contry;
}
}
二、 字元編碼
通過向文字編輯軟體中只單獨輸入“聯通”引出了字元編碼問題。
這個問題說明“聯通”這兩個漢字在編碼時用的是txt文字編輯器預設的gbk編碼,但是在解碼時,解碼程式把“聯通”經gbk編碼之後的位元組碼誤認為是UTF-8,所以按照UTF-8的格式對其進行解碼,所以就出錯了。
下面通過程式實驗“聯通”的編碼和解碼:
//建立字串“聯通”
String str = "聯通";
//將字串“聯通”用gbk編碼表編碼
byte[] buf = str.getBytes("gbk");
//輸出編碼後的二進位制資料
for(byte b : buf)
{
System.out.println(Integer.toBinaryString(b&255));
}
編碼方式是程式中經常出錯的地方,特別是在編寫jsp程式碼和後臺以及資料庫互動時更容易出錯。
三、 位元組陣列
ByteArrayInputStream:在構造的時候,需要接收資料來源,而且資料來源是一個位元組陣列
ByteArrayOutputStream:在構造的時候,不用定義資料目的,因為該物件中已經內部封裝了可變位元組長度的位元組陣列,這就是資料目的地。
因為這兩個流物件都操作的陣列,並沒有使用系統資源。 所以,不用進行close關閉
publicclass ByteArrayStreamDemo
{
publicstaticvoid main(String[] args)
{
//資料來源
ByteArrayInputStream bis = new ByteArrayInputStream("skdjfkds".getBytes());
//資料目的
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int by = 0;
while((by = bis.read())!=-1)
{
bos.write(by);
}
System.out.println(bos.size());
System.out.println(bos.toString());
//陣列輸出流的全部內容寫入到指定的輸出流引數中
//bos.writeTo(new FileInputStream("..."));
}
}
四、 物件流
ObjectOutputStream:
ObjectOutputStream 將 Java 物件的基本資料型別和圖形寫入 OutputStream。可以使用 ObjectInputStream 讀取(重構)物件。通過在流中使用檔案可以實現物件的持久儲存。
如果流是網路套接字流,則可以在另一臺主機上或另一個程序中重構物件。
只能將支援 java.io.Serializable 介面的物件寫入流中。
writeObject() 方法用於將物件寫入流中。所有物件(包括 String 和陣列)都可以通過 writeObject 寫入。
可將多個物件或基元寫入流中。必須使用與寫入物件時相同的型別和順序從相應 ObjectInputstream 中讀回物件。
ObjectInputStream:
ObjectInputStream 用於恢復那些以前序列化的物件。
其他用途包括使用套接字流在主機之間傳遞物件,或者用於編組和解組遠端通訊系統中的實參和形參。
Object readObject() 從 ObjectInputStream 讀取物件
publicclass ObjectStreamDemo
{
publicstaticvoid main(String[] args) throws Exception
{
//writeobj();
readobj();
}
publicstaticvoid readobj()throws Exception
{
//建立ObjectInputStream開啟obj.txt檔案
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));
//從ois流中獲取Person物件
Person p = (Person)ois.readObject();
//列印物件資訊
System.out.println(p);
//關閉流
ois.close();
}
publicstaticvoid writeobj()throws Exception
{
//建立ObjectOutputStream物件,並開啟一個檔案流物件
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));
//把Person物件寫入檔案中
oos.writeObject(new Person("zhangsna",20,"kr"));
//關閉ObjectOutputStream流
oos.close();
}
}
五、管道流
PipedInputStream:
管道輸入流應該連線到管道輸出流;
管道輸入流提供要寫入管道輸出流的所有資料位元組。
通常,資料由某個執行緒從 PipedInputStream 物件讀取,並由其他執行緒將其寫入到相應的 PipedOutputStream。
不建議對這兩個物件嘗試使用單個執行緒,因為這樣可能死鎖執行緒。
管道輸入流包含一個緩衝區,可在緩衝區限定的範圍內將讀操作和寫操作分離開。
PipedOutputStream:
可以將管道輸出流連線到管道輸入流來建立通訊管道。
管道輸出流是管道的傳送端。
通常,資料由某個執行緒寫入 PipedOutputStream 物件,並由其他執行緒從連線的 PipedInputStream 讀取。
不建議對這兩個物件嘗試使用單個執行緒,因為這樣可能會造成該執行緒死鎖。
使用管道流時,經常伴隨使用多執行緒技術。因為管道流中是兩個物件:寫入流和讀取流。這兩個流要同時執行才能成功,所以要用多執行緒。
class Read implements Runnable
{
private PipedInputStream in;
Read(PipedInputStream in)
{
this.in = in;
}
publicvoid run()
{
try
{
//建立位元組陣列用來存放讀取到的位元組資料
byte[] buf = newbyte[1024];
//讀取接收到的資料
int len = in.read(buf);
//將接收到的資料列印
System.out.println(new String(buf,0,len));
in.close();
}
catch(IOException e)
{
thrownew RuntimeException("管道流讀取失敗");
}
}
}
//寫入流執行緒
class Write implements Runnable
{
private PipedOutputStream out;
Write(PipedOutputStream out)
{
this.out = out;
}
publicvoid run()
{
try
{
//向管道流中寫資料
out.write("管道流對接試驗".getBytes());
Thread.sleep(10000);
//關閉管道流
out.close();
}
catch(Exception e)
{
thrownew RuntimeException("管道流讀取失敗");
}
}
}
publicclass PipedStreamDemo
{
publicstaticvoid main(String[] args) throws IOException
{
//建立讀取管道流
PipedInputStream in = new PipedInputStream();
//建立寫入管道流
PipedOutputStream out = new PipedOutputStream();
//將讀取流和寫入流連線
in.connect(out);
Read r = new Read(in);
Write w = new Write(out);
//執行緒啟動
new Thread(r).start();
new Thread(w).start();
}
}
---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS開發</a>、<a href="http://edu.csdn.net"target="blank">.Net培訓</a>、期待與您交流! ----------------------