java中有兩套IO,一套是普通的IO,即jdk1.4之前就包含的IO,另一套是jdk1.4包括進(jìn)來(lái)的nio。本文指的是普通的IO。java中的IO是基于流的。流的概念可以這樣理解,即數(shù)據(jù)好像實(shí)在一根管子里面流動(dòng),而管子的兩端連接什么,則需要根據(jù)具體的輸入輸出需要來(lái)確定了。比如說(shuō),我想從文件輸入到屏幕顯示,則管子的一端(輸入端)連接的是文件,另一端連接的是屏幕。這個(gè)比方可能不是很準(zhǔn)確,但目前先大概這樣理解了:-)。
java的io有兩類,一類是基于字節(jié)流的,基類是InputStream/OutputStream,另一類是基于字符流的,基類是Reader/Writer,注意基于Java的字符使用Unicode表示的,所以Reader/Writer的讀寫(xiě)操作都似乎基于雙字節(jié)的Unicode代碼單元。
下圖表示了Java io的結(jié)構(gòu)(圖片來(lái)自:http://www.unix.com.ua/orelly/java-ent/jnut/figs/JN3_1101.gif):
在學(xué)習(xí)時(shí)應(yīng)該注意的是,基于字節(jié)的io和基于字符的io是有一定的對(duì)應(yīng)關(guān)系的,掌握這些對(duì)應(yīng)關(guān)系,可以更快的掌握java io。
基于字節(jié)流的輸入的類:
1) ByteArrayInputStream:把內(nèi)存中的一個(gè)緩沖區(qū)作為InputStream使用
2) StringBufferInputStream:把一個(gè)String對(duì)象作為InputStream
3) FileInputStream:把一個(gè)文件作為InputStream,實(shí)現(xiàn)對(duì)文件的讀取操作
4) PipedInputStream:實(shí)現(xiàn)了pipe的概念,主要在線程中使用
5) SequenceInputStream:把多個(gè)InputStream合并為一個(gè)InputStream
基于字節(jié)流的輸出的類:
1) ByteArrayOutputStream:把信息存入內(nèi)存中的一個(gè)緩沖區(qū)中
2) FileOutputStream:把信息存入文件中
3) PipedOutputStream:實(shí)現(xiàn)了pipe的概念,主要在線程中使用
4) SequenceOutputStream:把多個(gè)OutStream合并為一個(gè)OutStream
基于字符流的輸入的類:
1) CharArrayReader:與ByteArrayInputStream對(duì)應(yīng)
2) StringReader:與StringBufferInputStream對(duì)應(yīng)
3) FileReader:與FileInputStream對(duì)應(yīng)
4) PipedReader:與PipedInputStream對(duì)應(yīng)
基于字符流的輸出的類:
1) CharArrayWrite:與ByteArrayOutputStream對(duì)應(yīng)
2) StringWrite:無(wú)與之對(duì)應(yīng)的以字節(jié)為導(dǎo)向的stream
3) FileWrite:與FileOutputStream對(duì)應(yīng)
4) PipedWrite:與PipedOutputStream對(duì)應(yīng)
以字符為導(dǎo)向的stream基本上對(duì)有與之相對(duì)應(yīng)的以字節(jié)為導(dǎo)向的stream。兩個(gè)對(duì)應(yīng)類實(shí)現(xiàn)的功能相同,只是在操作時(shí)的導(dǎo)向不同。如 CharArrayReader和ByteArrayInputStream的作用都是把內(nèi)存中的一個(gè)緩沖區(qū)作為InputStream使用,所不同的 是前者每次從內(nèi)存中讀取一個(gè)字節(jié)的信息,而后者每次從內(nèi)存中讀取一個(gè)Unicode字符(2個(gè)字節(jié))。
InputStreamReader和OutputStreamReader:把一個(gè)以字節(jié)為導(dǎo)向的stream轉(zhuǎn)換成一個(gè)以字符為導(dǎo)向的stream。
java中基于字節(jié)流的io還有一個(gè)重要的概念,裝飾類。即上圖中InputStream和OutputStream的子類中帶有Filter*類的子類,通過(guò)這些裝飾類可以給io添加新的功能。一個(gè)典型的應(yīng)用實(shí)例便是如果想要一個(gè)基于字節(jié)流的文件輸入,而又想提高效率而采用緩沖的話,可以按照以下代碼實(shí)現(xiàn):
File f = new File("c:\\test.dat);
FileInputStream fis = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(fis);
然后就可以對(duì)這個(gè)流采用帶有緩沖的輸入了。下面詳細(xì)介紹一下裝飾類:
InputStream的裝飾類:
1) DataInputStream:從stream中讀取基本類型(int、char等)數(shù)據(jù)。
2) BufferedInputStream:使用緩沖區(qū)
3) LineNumberInputStream:會(huì)記錄input stream內(nèi)的行數(shù),然后可以調(diào)用getLineNumber()和setLineNumber(int)
4) PushbackInputStream:很少用到,一般用于編譯器開(kāi)發(fā)
OutputStream的裝飾類
1) DataIOutputStream:往stream中輸出基本類型(int、char等)數(shù)據(jù)。
2) BufferedOutputStream:使用緩沖區(qū)
3) PrintStream:產(chǎn)生格式化輸出
在基于字符流的io中,與上述的基于字節(jié)流的裝飾類的對(duì)應(yīng)關(guān)系如下:
Reader的子類:
1) 沒(méi)有與DataInputStream對(duì)應(yīng)的類。除非在要使用readLine()時(shí)改用BufferedReader,否則使用DataInputStream
2) BufferedReader:與BufferedInputStream對(duì)應(yīng)
3) LineNumberReader:與LineNumberInputStream對(duì)應(yīng)
4) PushBackReader:與PushbackInputStream對(duì)應(yīng)
Writer的子類:
1) BufferedWriter:與BufferedOutputStream對(duì)應(yīng)
2) PrintWriter:與PrintStream對(duì)應(yīng)
如果想隨機(jī)讀寫(xiě)文件,可以使用RandomAccessFile類:
1) 可通過(guò)RandomAccessFile對(duì)象完成對(duì)文件的讀寫(xiě)操作
2) 在產(chǎn)生一個(gè)對(duì)象時(shí),可指明要打開(kāi)的文件的性質(zhì):r,只讀;w,只寫(xiě);rw可讀寫(xiě)
3) 可以直接跳到文件中指定的位置
參考:
徹底明白 Java 語(yǔ)言中的IO系統(tǒng) http://dev.yesky.com/105/7570105.shtml
精通Java網(wǎng)絡(luò)編程 汪曉平 清華大學(xué)出版社 2005 9
文章來(lái)源:http://tangwei312tom.blog.163.com/blog/static/22473192200881410343504