所有類的根接口:InputStream/OutputStream
一、底層的還是裝飾的
1、底層的直接與文件系統或者硬件打交道的類(充當數據源的類):
包括InputStream和OutPutStream兩大類,分別用于輸入和輸出,數據源可以是bytes array,String對象,file文件,stream序列等:
- FileInputStream/FileOutputStream
- ByteArrayInputStream/ByteArrayOutputStream
- StringBufferInputStream/StringBufferOutputStream
等,具體參看下面的java io類圖
2、充當裝飾功能的io類,通過裝飾底層的類來實現更高級的功能,繼承自FilterOutputStream/FilterOutputStream,包括:
- BufferedOutputStream/BufferedInputStream
- Datainputstream/Dataoutputstream
等,具體參看下面的java io類圖
使用FilterOutputStream/FilterOutputStream時,首先創建一個數據源IO,然后根據需要的功能創建裝飾類io,其構造函數的參數為已創建的數據源io。
二、面向字符還是面向字節
同時,java的IO體系又可以分成:inputStream/outputStream和reader/writer兩類:
(1) Reader/Writer是面向Unicode字符的(Characters)
(2) InputStream/OutputStream是直接面向字節的(bytes)。
Reader/Writer繼承體系之所以存在,最重要的原因是為了國際化,舊式I/O stream 的繼承體系僅僅支持8-bit byte stream,而且無法處理16-bit unicode 字符。由于unicode被用于字符國際化,所以加入Reader/Writer以便在所有的io動作上提供對unicode的支持。
幾乎所有的java io stream classes都有相應的Reader和Writer來提供對unicode的支持,但是在某些場合,使用byte-oriented InputStream和OutPutStream才是正取的方法,最合理的方式是盡可能先嘗試使用Read和Writer,其次才使用byte-oriented庫。
三、從InputStream/OutPutStream到Reader/Writer的轉換
InputStreamReader和OutputStreamWriter,可以把一個以字節為導向的stream轉換成一個以字符為導向的stream。
Java 1.0 class(byte oriented) Java 1.1 class(unicode character oriented)
裝飾前的行為
InputStream Reader 轉換器:InputStreamReader
OutputStreamReader Writer 轉換器:OutputStreamWriter
FileInputSream FileOutputStream
FileReader FileWriter
StringBufferInputStream StringReader/StringWriter
ByteArrayInputStream ByteArrayOutputStream
CharArrayReader CharArrayWriter
裝飾后的行為
BufferedInputStream BufferedOutputStream
BufferedReader BufferedWriter
PrintStream PrintWriter
四、示例
DataInputStream和DataOutputStream
Java中除了二進制文件和使用文本文件外還有基于Data的數據操作,這里的Data指的是Java的基本數據類型和String。基本數據類型包括byte、int、char、long、float、double、boolean和short。
例子:
protected void connect (Socket socket)
throws IOException, SocketException
{
this.socket = socket;
applyTimeout();
serverIn = new DataInputStream (
new BufferedInputStream (socket.getInputStream ())
);
serverOut = new DataOutputStream(
new BufferedOutputStream(socket.getOutputStream(), 2048)
);
usable = true;
cnt[CONNECT]++;
setChanged();
notifyObservers();
}
在DataInputStream和DataOutputStream兩個類中的方法都很簡單,基本結構為readXXXX()和writeXXXX()其中XXXX代表基本數據類型或者String。