.方便的IO操作是每個成功的語言所必須具有的,但是要有好的IO庫可不是件容易的事情,
因為不僅有三種不同的種類的IO需要考慮(檔案、控制台、網路連接),而且需要通過大量不同的方式與它們通訊(順序、隨機訪問、二進位、字元、按行、按字等等)。 2.Java庫的IO類分割為輸入與輸出兩個部分,通過繼承,從InputStream(輸入資料流)衍生的所有類都擁有名為read()的基本方法,用於讀取單個位元組或者位元組數組。類似地,從OutputStream衍生的所有類都擁有基本方法write(),用於寫入單個位元組或者位元組數組。然而,我們通常不會用到這些方法;它們之所以存在,是因為更複雜的類可以利用它們,以便提供一個更有用的介面。因此,我們很少用單個類建立自己的系統對象。一般情況下,我們都是將多個對象重疊在一起,提供自己期望的功能。我們之所以感到Java的流庫(Stream Library)異常複雜,正是由於為了建立單獨一個結果流,卻需要建立多個對象的緣故。
很有必要按照功能對類進行分類。庫的設計者首先決定與輸入有關的所有類都從InputStream繼承,而與輸出有關的所有類都從OutputStream繼承 3.InputStream 的類型1) ByteArrayInputStream (位元組數組)允許記憶體中的一個緩衝區作為InputStream使用 從中提取位元組的緩衝區/作為一個資料來源使用。通過將其同一個FilterInputStream對象串連,可提供一個有用的介面(2) StringBufferInputStream (String對象)將一個String轉換成InputStream 一個String(字串)。基礎的實施方案實際採用一個StringBuffer(字串緩衝)/作為一個資料來源使用。通過將其同一個FilterInputStream對象串連,可提供一個有用的介面(3) 檔案 FileInputStream 用於從檔案讀取資訊 代表檔案名稱的一個String,或者一個File或FileDescriptor對象/作為一個資料來源使用。通過將其同一個FilterInputStream對象串連,可提供一個有用的介面
(4) “管道”,它的工作原理與現實生活中的管道類似:將一些東西置入一端,它們在另一端出來。 (5) 一系列其他流,以便我們將其統一收集到單獨一個流內。
(6) 其他起源地,如Internet 4.OutputStream的類型
(1).ByteArrayOutputStream 在記憶體中建立一個緩衝區。我們發送給流的所有資料都會置入這個緩衝區。 可選緩衝區的初始大小/用於指出資料的目的地。若將其同FilterOutputStream對象串連到一起,可提供一個有用的介面
(2).FileOutputStream 將資訊發給一個檔案 用一個String代表檔案名稱,或選用一個File或FileDescriptor對象/用於指出資料的目的地。若將其同FilterOutputStream對象串連到一起,可提供一個有用的介面 5.FilterInputStream類型(1).DataInputStream ,與DataOutputStream搭配使用,可以按照可移植方式從流讀取基礎資料型別 (Elementary Data Type),其建構函式參數為InputStream;(2).BufferedInputstream, 可以防止每次讀取是都得進行實際的寫操作,代表"使用緩衝區",建構函式參數仍為InputStream; 6.FilterOutputStream類型(1).DataOutputStream.....(2).PrintStream,用於產生格式化輸出,其中DataOutputStream處理資料的儲存,PrintStream處理顯示,建構函式參數為OutputStream;(3).BufferedOutputStream..... 5.Reader和Writer(提供相容Unicode與面向字元的IO功能)(1).為了關聯"位元組"階層和"字元"階層需要適配器InputStreamReader 可以把 InputStream 轉換為Reader,OutputStreamReader 可以把OutputStream 轉換為 Writer (2). FileInputStream 對應 FileReader;FileOutputStream 對應 FileWriter;StringBufferInputStream 對應 StringReader; (3).FilterInputStream 對應 FilterReaderFilterOutputStream 對應 FilterWriterBufferedInputStream 對應 BufferedReaderBufferedOutputStream 對應 BufferedWriterPrintStream 對應 PrintWriterStreamTokenizer 對應 StreamTokenizer 6..操作Java的IO的一般步驟:(1).首先建立資料來源IO,(2).然後根據需要建立需要封裝的IO類,其建構函式參數為已建立的資料來源IO;(3).操作得到的IO控制代碼;樣本程式: 我們以建立一個具有緩衝的檔案輸入資料流為例,假定需要從磁碟讀取檔案“E://Java/data.txt”:
// 建立一個FileInputStream:
FileInputStream fileInput = new FileInputStream(“E://Java/data.txt”);
// 建立一個BufferedInputStream:
BufferedInputStream bufferedInput = new BufferedInputStream(fileInput);
// 現在得到的bufferedInput即是具有緩衝的檔案輸入資料流
或者進一步簡寫如下:
InputStream input = new BufferedInputStream(
new FileInputStream(“E://Java/data.txt”));
// 現在得到的input即是具有緩衝的檔案輸入資料流 6.常見讀寫樣本:(1).讀寫文字檔,程式功能:讀取一文字檔到記憶體中的String類型變數中,在終端顯示內容,並複製內容到另外的文字檔中package MyJava.Base;import java.io.*;public class TextReaderDemo
{
public static void main(String[] args) throws IOException
{
//讀取檔案中內容到BufferedReader;
BufferedReader in=new BufferedReader(new FileReader("E://Java//JCreator2.5//加密解密.txt"));
String str=new String();
String s=new String();
while((s=in.readLine())!=null)
str+=s+"/n";
in.close();
System.out.println(str);
PrintWriter out=new PrintWriter(new BufferedWriter(new FileWriter("E://Java//JCreator2.5//加密解密(copyt).txt")));
BufferedReader outbfreader=new BufferedReader(new StringReader(str));
while((s=outbfreader.readLine() )!=null)
out.println(s);
out.close();
} (2).從控制台輸入,Java中從控制台輸入比起C++好像複雜多了,畢竟C++只需要cin和cout就行了,Java有點複雜BufferedReader stdin=new BufferedReader(new InputStreamReader(System.in));String str=stdin.readLine(); (3).從記憶體中讀取StringReader in2=new StringReader(str); //其中str為String類型int ch;while((ch=in2.read())!=-1) System.out.printl((char)ch); (4).讀取二進位檔案,讀寫二進位檔案主要是通過位元組流,而不是字元流,二進位檔案可是圖片之類的,下面的程式功能是複製一副圖片package MyJava.Base;import java.io.*;public class BinaryReaderDemo
{
public static void main(String[] args) throws IOException
{
//讀取圖片檔案資料到InputStream;
// byte bt[1024];
// FileInputStream in=new FileInputStream(new File("E://Java//JCreator2.5//加密解密.txt"));
File file=new File("C://Documents and Settings//luliuyan_1985//My Documents//My Pictures//cs.jpg");
if(!file.exists() && !file.canRead())
{
System.out.println("file don't exist or file cannot read!!");
System.exit(1);
}
long len=file.length();
byte[] buffer=new byte[(int)len];
FileInputStream filein=new FileInputStream(file);
//////////////////////////////////////////////////////////
File file2=new File("E://Java//JCreator2.5//cs(copy).jpg");
if(!file2.exists())
{
file2.createNewFile();
}
FileOutputStream fileout=new FileOutputStream(file2,true);
int ch=0;
///////////////////////////////
//方式一:
/*
while((ch=filein.read())!=-1)
{
fileout.write(ch);
}
*/
//方式二,執行效率比方式一高:
/*
while((ch=filein.read(buffer))!=-1)
{
fileout.write(buffer);
}
*/
//方式三:
while((ch=filein.read(buffer,0,(int)len))!=-1)
{
fileout.write(buffer,0,(int)len);
}
filein.close();
fileout.close();
}} 7.Java的序列化(1).序列化的過程就是對象寫入位元組流和從位元組流中讀取對象。將對象狀態轉換成位元組流之後,可以用java.io包中的各種位元組流類將其儲存到檔案中,管道到另一線程中或通過網路連接將對象資料發送到另一主機。對象序列化功能非常簡單、強大,在RMI、Socket、JMS、EJB都有應用。對象序列化問題在網路編程中並不是最激動人心的課題,但卻相當重要,具有許多實用意義。
一:對象序列化可以實現分布式對象。主要應用例如:RMI要利用對象序列化運行遠程主機上的服務,就像在本地機上運行對象時一樣。
二:java對象序列化不僅保留一個對象的資料,而且遞迴儲存對象引用的每個對象的資料。可以將整個對象層次寫入位元組流中,可以儲存在檔案中或在網路連接上傳遞。利用對象序列化可以進行對象的"深複製",即複製對象本身及引用的對象本身。序列化一個對象可能得到整個對象序列。
java序列化比較簡單,通常不需要編寫儲存和恢複對象狀態的定製代碼。實現java.io.Serializable介面的類對象可以轉換成位元組流或從位元組流恢複,不需要在類中增加任何代碼。只有極少數情況下才需要定製代碼儲存或恢複對象狀態。這裡要注意:不是每個類都可序列化,有些類是不能序列化的,例如涉及線程的類與特定JVM有非常複雜的關係 (2).序列化的執行個體(過段時間給出集合容器方面知識的小程式)