當前位置:首頁 » Java教學 » Java IO係統

Java IO係統

Java IO係統用法

6. Java IO係統

JDK1.0輸入流

InputStream


ByteArrayInputStream


FileInputStream


FilterInputStream


ObjectInputStream


PipedInputStream


SequenceInputStream


BufferedInputStream


DataInputStream


PushbackInputStream


LineNumberInputStream

JDK1.1輸入流

Reader


BufferedReader


FilterReader


PipedReader


StringReader


InputStreamReader


CharArrayReader


FileReader


PushbackReader


LineNumberReader


JDK1.0輸出流

OutputStream


BufferedOutputStream


DataOutputStream


PrintStream


ByteArrayOutputStream


FileOutputStream


FilterOutputStream


ObjectOutputStream


PipedOutputStream

JDK1.1輸出流


Writer


BufferedWriter


FilterWriter


PipedWriter


StringWriter


FileWriter


PrintWriter


OutputStreamWriter


CharArrayWriter

如果你剛剛接觸Java的IO部分, 你可能會感覺無從入手, 確實Java提供了過多的類,反而讓人感到很亂。

可將Java庫的IO類分為輸入與輸出兩個部分, 在1.0版本中提供了兩個抽象基類, 所有輸入的類都從InputStream繼承, 所有輸出的類都從OutputStream繼承, 1.1提供了兩個新的基類, 負責輸入的Reader與輸出的Writer, 但它們並不是用來替換原來老的InputStream與OutputStream, 它們主要是讓Java能更好的支持國際化的需求。 原來老的IO流層隻支持8位字節流, 不能很好地控製16位Unicode字符。 Java內含的char是16位的Unicode, 所以添加了Reader和Writer層次以提供對所有IO操作中的Unicode的支持。 除此之外新庫也對速度進行了優化, 可比舊庫更快地運行。


InputStream的類型:

1  字節數組

2  String對象

3  文件

4  管道, 可以從另外一個輸出流得到一個輸入流

5  一係列的其他流, 可以將這些流統一收集到單獨的一個流內。

6  其他起源(如socket流等)


還有一個是File類, Java中一個目錄也是一個文件,可以用file.isFile()和file.isDirectory()來進行判斷是文件還是目錄。 File 對象可能作為參數轉換為文件流進行操作。 具體操作參照Java IO API。


常用方法:

/**

 * 拚文件名, 在windows(\)跟unix(/)上的文件分割符是不一樣的

 * 可以通過File類的靜態成員變量separator取得

 */

public static String concatFileName(String dir, String fileName) {

String fullFileName = "";

if (dir.endsWith(File.separator)) {fullFileName = dir + fileName;

} else {fullFileName = dir + File.separator + fileName;}

return fullFileName; }


/**

 * 從控製台讀取輸入的數據, System.in (InputStream) 先轉換至InputStreamReader再用

 * BufferedReader進行讀取.

 *

 */

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

String str = "";

while (str != null) {str = in.readLine();// process(str); }


/**

 * 從文件中按行進行讀取數據處理

 */

BufferedReader in = new BufferedReader(new FileReader("infilename"));

String str;

while ((str = in.readLine()) != null) {// process(str); }

in.close();


/**

 * 寫數據至一個新的文件中去.

 */

BufferedWriter out = new BufferedWriter(new FileWriter("outfilename"));

out.write("a String");

out.close();


/**

 * 追加新的數據到一個文件中去, 如果原文件不存在

 * 則新建這個文件.

 */

BufferedWriter out = new BufferedWriter(new FileWriter("filename", true));

out.write("aString");

out.close();


/**

 * 將一個可序列化的Java的object以流方式寫到一個文件中去中.

 */

ObjectOutput out = new ObjectOutputStream(new FileOutputStream("filename.ser"));

out.writeObject(object);

out.close();

/**

 * 從文件中恢複序列化過的Java Object

 */

ObjectInputStream in = new ObjectInputStream(new FileInputStream("filename.ser"));

Object object = (Object) in.readObject();

in.close();


/**

 * 以指定的編碼方式從文件中讀取數據

 */

BufferedReader in = new BufferedReader(new InputStreamReader(

 new FileInputStream("infilename"), "UTF8"));

String str = in.readLine();


/**

 * 以指定的編碼方式寫數據到文件中

 */

Writer out = new BufferedWriter(new OutputStreamWriter(

new FileOutputStream("outfilename"), "UTF8"));

out.write("a String");

out.close();


由上麵的例子可以看出, 流之間可以互相轉換, 如果想對流進行字符操作最好將之轉換成BufferedReader與BufferedWriter這樣可以提高讀寫的效率。

需要注意的是一般來說流的大小是得不到的, 雖然一般的InputStream都有一個available()的方法可以返回這個流可以讀到的字節數, 不過這個方法有時候不會很準確, 比如在讀取網絡傳輸的流的時候, 取到的長度並不一定是真實有效的長度。


大家在寫程序的時候可能已經注意到一些類都繼承了java.io.Serializable這個接口, 其實繼承了這個接口之後這個類的本身並不做任何事情, 隻是這個類可以被序列化並通過流來進行傳輸, 並可被還原成原Object。 這個流可以通過網絡傳輸(EJB 中進行傳遞參數和返回值的Data Class), 也可以保存到文件中去(ObjectOutputStream)。