7777精品伊人久久久大香线蕉经典版下载,一区二区免费在线观看,国产电影一区在线http://www.aygfsteel.com/gnilling/category/37845.html&nbsp&nbsp&nbsp The more you share, the more you getzh-cnTue, 24 Feb 2009 12:43:20 GMTTue, 24 Feb 2009 12:43:20 GMT60弄清Java中的IOhttp://www.aygfsteel.com/gnilling/archive/2009/02/24/256506.htmlAlbert LingAlbert LingTue, 24 Feb 2009 12:29:00 GMThttp://www.aygfsteel.com/gnilling/archive/2009/02/24/256506.htmlhttp://www.aygfsteel.com/gnilling/comments/256506.htmlhttp://www.aygfsteel.com/gnilling/archive/2009/02/24/256506.html#Feedback0http://www.aygfsteel.com/gnilling/comments/commentRss/256506.htmlhttp://www.aygfsteel.com/gnilling/services/trackbacks/256506.html

    Java的核心庫java.io提供了全面的IO接口,包括:文件讀寫,標準設備輸出等等。JavaIO是以流為基礎進行輸入輸出的,所有數據被串行化寫入輸出流,或者從輸入流讀入。在具體使用中很多初學者對Java.io包的使用非常含糊,本文將詳細解說關于Java.io的使用。

-----------------------------------------------------
  一. InputOutput
   
stream代表的是任何有能力產出數據的數據源,或是任何有能力接收數據的接收源。在JavaIO系統中,所有的stream(包括InputOut stream)都包括兩種類型:
 
1.1 以字節為導向的stream
  以字節為導向的stream,表示以字節為單位從stream中讀取或往stream中寫入信息。以字節為導向的stream包括下面幾種類型:
input
stream
     
1) ByteArrayInputStream:把內存中的一個緩沖區作為InputStream使用
     
2) StringBufferInputStream:把一個String對象作為InputStream
     
3) FileInputStream:把一個文件作為InputStream,實現對文件的讀取操作
     
4) PipedInputStream:實現了pipe的概念,主要在線程中使用
     
5) SequenceInputStream:把多個InputStream合并為一個InputStream
Out
stream
     
1) ByteArrayOutputStream:把信息存入內存中的一個緩沖區中
     
2) FileOutputStream:把信息存入文件中
     
3) PipedOutputStream:實現了pipe的概念,主要在線程中使用
     
4) SequenceOutputStream:把多個OutStream合并為一個OutStream
 
1.2 Unicode字符為導向的stream
  以Unicode字符為導向的stream,表示以Unicode字符為單位從stream中讀取或往stream中寫入信息。以Unicode字符為導向的stream包括下面幾種類型:
Input
Stream
     
1) CharArrayReader:與ByteArrayInputStream對應
     
2) StringReader:與StringBufferInputStream對應
     
3) FileReader:與FileInputStream對應
     
4) PipedReader:與PipedInputStream對應
Out
Stream
     
1) CharArrayWrite:與ByteArrayOutputStream對應
     
2) StringWrite:無與之對應的以字節為導向的stream
     
3) FileWrite:與FileOutputStream對應
     
4) PipedWrite:與PipedOutputStream對應
   以字符為導向的stream基本上對有與之相對應的以字節為導向的stream。兩個對應類實現的功能相同,字是在操作時的導向不同。如 CharArrayReader:和ByteArrayInputStream的作用都是把內存中的一個緩沖區作為InputStream使用,所不同的 是前者每次從內存中讀取一個字節的信息,而后者每次從內存中讀取一個字符。
 
1.3 兩種不現導向的stream之間的轉換
   
InputStreamReaderOutputStreamReader:把一個以字節為導向的stream轉換成一個以字符為導向的stream

--------------------------------------------------
    . stream添加屬性
 
2.1 “stream添加屬性的作用
  運用上面介紹的Java中操作IOAPI,我們就可完成我們想完成的任何操作了。但通過FilterInputStreamFilterOutStream的子類,我們可以為stream添加屬性。下面以一個例子來說明這種功能的作用。
  如果我們要往一個文件中寫入數據,我們可以這樣操作:
FileOutStream fs = new FileOutStream(“test.txt”);
   然后就可以通過產生的fs對象調用write()函數來往test.txt文件中寫入數據了。但是,如果我們想實現先把要寫入文件的數據先緩存到內存 中,再把緩存中的數據寫入文件中的功能時,上面的API就沒有一個能滿足我們的需求了。但是通過FilterInputStream FilterOutStream的子類,為FileOutStream添加我們所需要的功能。
 
2.2 FilterInputStream的各種類型
   
2.2.1 用于封裝以字節為導向的InputStream
     
1) DataInputStream:從stream中讀取基本類型(intchar等)數據。
     
2) BufferedInputStream:使用緩沖區
     
3) LineNumberInputStream:會記錄input stream內的行數,然后可以調用getLineNumber()setLineNumber(int)
     
4) PushbackInputStream:很少用到,一般用于編譯器開發
   
2.2.2 用于封裝以字符為導向的InputStream
     
1) 沒有與DataInputStream對應的類。除非在要使用readLine()時改用BufferedReader,否則使用DataInputStream
     
2) BufferedReader:與BufferedInputStream對應
     
3) LineNumberReader:與LineNumberInputStream對應
     
4) PushBackReader:與PushbackInputStream對應
 
2.3 FilterOutStream的各種類型
   
2.2.3 用于封裝以字節為導向的OutputStream
     
1) DataIOutStream:往stream中輸出基本類型(intchar等)數據。
     
2) BufferedOutStream:使用緩沖區
     
3) PrintStream:產生格式化輸出
   
2.2.4 用于封裝以字符為導向的OutputStream
     
1) BufferedWrite:與對應
     
2) PrintWrite:與對應

--------------------------------------------------

    三. RandomAccessFile
     
1) 可通過RandomAccessFile對象完成對文件的讀寫操作
     
2) 在產生一個對象時,可指明要打開的文件的性質:r,只讀;w,只寫;rw可讀寫
     
3) 可以直接跳到文件中指定的位置



Albert Ling 2009-02-24 20:29 發表評論
]]>
對象的序列化和反序列化http://www.aygfsteel.com/gnilling/archive/2009/02/22/256133.htmlAlbert LingAlbert LingSun, 22 Feb 2009 15:07:00 GMThttp://www.aygfsteel.com/gnilling/archive/2009/02/22/256133.htmlhttp://www.aygfsteel.com/gnilling/comments/256133.htmlhttp://www.aygfsteel.com/gnilling/archive/2009/02/22/256133.html#Feedback0http://www.aygfsteel.com/gnilling/comments/commentRss/256133.htmlhttp://www.aygfsteel.com/gnilling/services/trackbacks/256133.html

當兩個進程在進行遠程通信時,彼此可以發送各種類型的數據。無論是何種類型的數據,都會以二進制序列的形式在網絡上傳送。發送方需要把這個Java對象轉換為字節序列,才能在網絡上傳送;接收方則需要把字節序列再恢復為Java對象。

Java對象轉換為字節序列的過程稱為對象的序列化。

把字節序列恢復為Java對象的過程稱為對象的反序列化。

對象的序列化主要有兩種用途:

1 把對象的字節序列永久地保存到硬盤上,通常存放在一個文件中;

2 在網絡上傳送對象的字節序列。

一.JDK類庫中的序列化API

java.io.ObjectOutputStream代表對象輸出流,它的writeObject(Object obj)方法可對參數指定的obj對象進行序列化,把得到的字節序列寫到一個目標輸出流中。

java.io.ObjectInputStream代表對象輸入流,它的readObject()方法從一個源輸入流中讀取字節序列,再把它們反序列化為一個對象,并將其返回。、

只有實現了SerializableExternalizable接口的類的對象才能被序列化。Externalizable接口繼承自Serializable接口,實現Externalizable接口的類完全由自身來控制序列化的行為,而僅實現Serializable接口的類可以采用默認的序列化方式

對象序列化包括如下步驟:

1 創建一個對象輸出流,它可以包裝一個其他類型的目標輸出流,如文件輸出流;

2 通過對象輸出流的writeObject()方法寫對象。

對象反序列化的步驟如下:

1 創建一個對象輸入流,它可以包裝一個其他類型的源輸入流,如文件輸入流;

2 通過對象輸入流的readObject()方法讀取對象。

下面讓我們來看一個對應的例子,類的內容如下:

package cn.albert.ling.p386;

import java.io.*;
import java.util.Date;

public class ObjectSaver {
    
    
/**
     * 
@author <a href="MailTo:ling.albert.cn@gmail.com">albert ling</a>
     * Creation date: 2009 2 22 
     
*/

    
public static void main(String[] args) throws Exception {

        File file 
= new File("D:\\temp.txt");
        ObjectOutputStream out 
= new ObjectOutputStream
        (
new FileOutputStream(file));
        
// 序列化對象
        Customer customer = new Customer("LS"24);
        out.writeObject(
"Morning!");
        out.writeObject(
new Date());
        out.writeObject(customer);
        out.writeInt(
123); // 寫入基本類型數據
        out.close();
        
// 反序列化對象
        ObjectInputStream in = new ObjectInputStream
        (
new FileInputStream(file));
        System.out.println(
"obj1=" + (String) in.readObject());
        System.out.println(
"obj2=" + (Date) in.readObject());
        Customer obj3 
= (Customer) in.readObject();
        System.out.println(
"obj3=" + obj3);
        
int obj4 = in.readInt();
        System.out.println(
"obj4=" + obj4);
        in.close();
        file.delete();
    }
}

class Customer implements Serializable {

    
private static final long serialVersionUID = 1L;
    
private String name;
    
private int age;
    
    
public Customer(String name, int age) {
        
this.name = name;
        
this.age = age;
    }

    
public String toString() {
        
return "name=" + name + ", age=" + age;
    }

}

 

二.實現Serializable接口

ObjectOutputStream只能對Serializable接口的類的對象進行序列化。默認情況下,ObjectOutputStream按照默認方式序列化,這種序列化方式僅僅對對象的非transient的實例變量進行序列化,而不會序列化對象的transient的實例變量,也不會序列化靜態變量。

ObjectOutputStream按照默認方式反序列化時,具有如下特點:

1)如果在內存中對象所屬的類還沒有被加載,那么會先加載并初始化這個類。如果在classpath中不存在相應的類文件,那么會拋出ClassNotFoundException

2)在反序列化時不會調用類的任何構造方法。

如果用戶希望控制類的序列化方式,可以在可序列化類中提供以下形式的writeObject()readObject()方法。

private void writeObject(java.io.ObjectOutputStream out) throws IOException

private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;

ObjectOutputStream對一個Customer對象進行序列化時,如果該對象具有writeObject()方法,那么就會執行這一方法,否則就按默認方式序列化。在該對象的writeObjectt()方法中,可以先調用ObjectOutputStreamdefaultWriteObject()方法,使得對象輸出流先執行默認的序列化操作。同理可得出反序列化的情況,不過這次是defaultReadObject()方法。

有些對象中包含一些敏感信息,這些信息不宜對外公開。如果按照默認方式對它們序列化,那么它們的序列化數據在網絡上傳輸時,可能會被不法份子竊取。對于這類信息,可以對它們進行加密后再序列化,在反序列化時則需要解密,再恢復為原來的信息。

默認的序列化方式會序列化整個對象圖,這需要遞歸遍歷對象圖。如果對象圖很復雜,遞歸遍歷操作需要消耗很多的空間和時間,它的內部數據結構為雙向列表。

在應用時,如果對某些成員變量都改為transient類型,將節省空間和時間,提高序列化的性能。

三.實現Externalizable接口

Externalizable接口繼承自Serializable接口,如果一個類實現了Externalizable接口,那么將完全由這個類控制自身的序列化行為。Externalizable接口聲明了兩個方法:

public void writeExternal(ObjectOutput out) throws IOException

public void readExternal(ObjectInput in) throws IOException , ClassNotFoundException

前者負責序列化操作,后者負責反序列化操作。

在對實現了Externalizable接口的類的對象進行反序列化時,會先調用類的不帶參數的構造方法,這是有別于默認反序列方式的。如果把類的不帶參數的構造方法刪除,或者把該構造方法的訪問權限設置為private、默認或protected級別,會拋出java.io.InvalidException: no valid constructor異常。

四.可序列化類的不同版本的序列化兼容性

凡是實現Serializable接口的類都有一個表示序列化版本標識符的靜態變量:

private static final long serialVersionUID;

以上serialVersionUID的取值是Java運行時環境根據類的內部細節自動生成的。如果對類的源代碼作了修改,再重新編譯,新生成的類文件的serialVersionUID的取值有可能也會發生變化。

類的serialVersionUID的默認值完全依賴于Java編譯器的實現,對于同一個類,用不同的Java編譯器編譯,有可能會導致不同的serialVersionUID,也有可能相同。為了提高哦啊serialVersionUID的獨立性和確定性,強烈建議在一個可序列化類中顯示的定義serialVersionUID,為它賦予明確的值。顯式地定義serialVersionUID有兩種用途:

1)在某些場合,希望類的不同版本對序列化兼容,因此需要確保類的不同版本具有相同的serialVersionUID

2在某些場合,不希望類的不同版本對序列化兼容,因此需要確保類的不同版本具有不同的serialVersionUID

 



Albert Ling 2009-02-22 23:07 發表評論
]]>
主站蜘蛛池模板: 玉林市| 泰州市| 广水市| 兴山县| 嘉义市| 彭山县| 淮安市| 重庆市| 连云港市| 大理市| 黔东| 科技| 庆城县| 贵德县| 定日县| 久治县| 江北区| 乐清市| 姜堰市| 日土县| 通榆县| 西乌| 名山县| 栖霞市| 石狮市| 阿拉善左旗| 灌云县| 合山市| 长治县| 济宁市| 建水县| 建昌县| 黄石市| 柞水县| 苏尼特右旗| 华坪县| 土默特左旗| 林州市| 保山市| 甘肃省| 大英县|