Thinking In Java----2017.1.29 IO流(完結版,乾貨)
1.File:
a.) FilenameFilter:
class DirFilter implementsFilenameFilter{
private Pattern pattern;
public DirFilter(String args) {
pattern = Pattern.compile(args);
}
@Override
publicbooleanaccept(File file, String filename) {
returnpattern.matcher(filename).matches();
}
}
File
String[] list;
if(args.length==0){
list= file.list();
}else{
list = file.list(new DirFilter(args[0]));
}
Arrays.sort(list,String.CASE_INSENSITIVE_ORDER);
for(String item :list){
System.out.println(item);
}
總結:list()方法會回掉FileNameaFilter介面的accept()方法,你可以在list()方法中指定FileNameFilter引數,這樣list()可以按照你想要的方式生成字元陣列,僅包含你需要的檔名。
accept()方法可以接收一個檔案和檔名,它是實現FileNnameFilter的最重要的方法,你可以指定你接受哪些檔案。
Pattern.compile(String regex) regex是正則表示式,這個方法生成一個按照指定正則表示式編譯的Pattern,通過這個matcher(String)生成一個Matcher,matches進行匹配,匹配到返回true。
2.輸入和輸出(位元組流):
read()讀單個位元組或者位元組陣列
write()寫單個位元組或者位元組陣列
SequenceInputStream:流序列
將兩個或者多個InputStreama物件轉換成單一的InputStream;
FilterInputStream:抽象類,為其他InputStream提供有用功能。
InputStream中有:
ByteArrayInputStream
StringBufferInputStream(已棄用) ---將String轉換成InputStream 接受String引數,底層實現用的事StringBuffer
FileInputStream
PipedInputStream
SequenceInputStream
FilterInputStream
OutputStream中有:
ByteArrayOutputStream
FileOutSputtream
PipedOutputStream
FilterOutputStream
修飾流:
FilterInputStream和FilterOutStream
它們為修飾器類提供了一個基類,“裝飾器”類把屬性或者有用的介面與輸出流連線了起來。
核心的”I/O 加上所有的修飾器,才能得到我們想要的I/O物件”
a.)FilterInputStream:
DataInputStream(InputStream) 允許我們讀取不同的基本資料型別和String物件,各種read()方法,如readByte()、readFloat()。-------從流中讀取
BufferedInputStream(InputStream):內部改變了InputStream的行為方式,對資料進行緩衝。------改變流的行為方式
b.)FilterOutStream:
DataOutStream(向流中寫入,負責資料的儲存)、PrintStream(負責資料的顯示)、BufferedOutStream
3.Reader和Writer(字元流):
Reader和Writer提供相容Unicode與面向字元的I/O功能
Reader和Writer是為了在所有的io操作中支援Unicode,為了國際化
InputStreamReader把InputStream轉換成Reader
OutputStreamWriter把OutputStream轉換成Writer
一般我們在編寫程式的時候,儘量使用Writer和Reader(幾乎所有原始I/O流類都有相應的Writer和Reader),不得已的時候選用面向位元組的類庫(java.util.zip類庫就是面向位元組的而不是面向字元的)
FileReader(Writer)
StringReader(Writer)
CharArrayReader(Writer)
PipedArrayReader(Writer)
修飾FilterWriter:
BufferedWriter
PrintWriter
2和3中最特殊的是DataOutPutStream,如果想以“可傳輸的” 格式儲存和檢索資料,它依然是首先。
4.RandomAccessFile(只適用於檔案,大多數功能由nio的儲存對映檔案代替):
RandomAccessFile用於大小已知的記錄組成的檔案,它是獨立的類,和InputStream和Op繼承結構無關。
它有檔案指標pointer
getFilePointer()指標位置
seek()檔案內移動新的位置
Length()判斷檔案大小
“r”“rw”--建構函式第二個引數,訪問方式
5.avaliable():
用來檢查還有多少個可供讀取的字元。
DataInputStreamd = newDataInputStream(new BufferedInputStream(new FileInputStream("D:\\abc.txt")));
while(d.available() != 0){
System.out.print("還有"+d.available()+"個:"+(char)d.readByte());
}
6.DataOutPutStream DataIntPutStream:
writeUTF()和readUTF()可以使得String和其他資料型別相混合
String s = "D:\\abcd.txt";
File file = new File(s);//為檔案指定編碼方式
if(!file.exists()){
file.createNewFile();
}
DataOutputStream d = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(s)));
d.writeInt(1);
d.writeByte(2);
d.writeLong(68548964896578964l);
d.writeDouble(85468468d);
d.writeBoolean(false);
d.writeChars("結束");
d.flush();
d.close();
DataInputStream di = new DataInputStream(new BufferedInputStream(new FileInputStream(s)));
System.out.println(di.readInt());
System.out.println(di.readByte());
System.out.println(di);
System.out.println(di.readLong());
System.out.println(di.readChar());
1
2
68548964896578964
?
為了保證所有的讀方法能正常工作,我們必須知道流中資料項所在的確切位置。所以他倆的時候,要麼知道資料儲存固定格式,要麼有額外資訊。
7.System.out和System.err被包裝成了printStream物件
System.in是inputStream,讀取它之前要進行包裝。
PrintWriter可以接受一個OutputStream,而printStream是OutputStream,所以必要的時候可以把System.out轉換成PrintWriter
8.標準I/O重定向:
System.setIn(InputStream)
System.setOut(PrintStream)
System.setErr(PrintStream)
重定向功能在特定情況下會很有用:
如果有了大量輸出,並且輸出滾動太快使得你無法閱讀的時候,你重定向輸出到一個檔案中,這樣方面閱讀。
如果你要一段重複多次的命令列程式,你可以重定向輸入到一個充滿命令列的檔案:
如下:我在abc裡寫了輸入,我重定向輸入abc,再把abc用作InputStream,把其中的內容輸出並重定向到abcd檔案中。
PrintStream console = System.out;
BufferedInputStream in = new BufferedInputStream(new FileInputStream("D:\\abc.txt"));
PrintStream out = new PrintStream(new FileOutputStream("D:\\abcd.txt"));
System.setIn(in);
System.setOut(out);
BufferedReader b = new BufferedReader(new InputStreamReader(System.in));
String s ;
while((s=b.readLine()) != null){
System.out.println(s);
}
b.close();
out.flush();
out.close();
in.close();
System.setOut(console);
9.程序控制:
Process p = new ProcessBuilder(xxxxxx).start();
10新I/O:
通道和緩衝期:
a.)通道:舊I/O類庫中 有3個類被修改了,用以產生FileChannel,他們分別是FileInputStrea,FileOutPutStream,和RandomAccessFile。
注意: 這些都是位元組流操作,Reader和Writer這種字元流的操作不能用於產生通道,但是Channel類提供了實用的方法,可以產生Writer和Reader。(你可以理解為Channel就是由一堆Byte構成的,所以它接受位元組流的操作,不接受字元流的操作)。
b.)緩衝器:我們可以通過allocate(大小)來告知分配多少空間從而生成一個緩衝器物件,它可以讀取和輸出資料,但是不能讀取和輸出物件,字串物件也不行。
FileChannel fc = new FileOutputStream(“data.txt”).getChannel();
fc.write(ByteBuffer.wrap("Some one".getBytes()));
fc.close();-----------通道用完要關起來
fc = new RandomAccessFile(“data.txt”, "rw").getChannel();
fc.position(fc.size());
fc.write(ByteBuffer.wrap(" Some two".getBytes()));
fc.close();
fc = new FileInputStream(“data.txt”).getChannel();
ByteBuffer buffer = ByteBuffer.allocate(SIZE);
fc.read(buffer);
buffer.flip();
while(buffer.hasRemaining()){
System.out.print((char)buffer.get());
};
wrap()方法將已經存在的位元組陣列“包裝到”ByteBuffer中。
allocate()方法分配ByteBuffer,nio的目標就是快速移動大量資料,因此ByteBuffer的大小就顯得尤為重要。
為了達到更高速度的可能,也可以使用allocateDirect(),它會產生一種與作業系統有更高耦合性的”直接緩衝器”,但是這種分配的開支會更大。
緩衝區是特定基本型別元素的線性有限序列。除內容外,緩衝區的基本屬性還包括容量(capacity)、限制(limit)和位置(position)還有標記(mark):
緩衝區的capacity是它所包含的元素的數量。緩衝區的capacity不能為負並且不能更改。
緩衝區的limit 是第一個不應該讀取或寫入的元素的索引。緩衝區的limit不能為負,並且不能大於其capacity。
緩衝區的position是下一個要讀取或寫入的元素的索引。緩衝區的位置不能為負,並且不能大於其limit。對於每個非 boolean 基本型別,此類都有一個子類與之對應。
在使用緩衝區進行輸入輸出資料之前,必須確定緩衝區的position,limit都已經設定了正確的值。
如果現在想用這個緩衝區進行通道的寫操作,由於write()方法將從position指示的位置開始讀取資料,在limit指示的位置停止,因此在進行寫操作前,先要將limit的值設為position的當前值,再將position的值設為0,這是為了得到正確的位元組。這個操作可以通過這個flip()方法實現。
flip()使緩衝區為一系列新的通道寫入或相對獲取 操作做好準備:它將限制設定為當前位置,然後將位置設定為0,即上邊的要求(紅色字體表示)。
所以,上邊的操作步驟為:buffer.flip();
out.write(buffer);
緩衝器的使用細節:
當你進行了Channel的read()操作之後,你的緩衝器裡就有一定長度的資料了,你用flip()操作可以把你當前資料的position設定為緩衝器的limit,然後把posiotion變成0,方便資料的提取,然後可以進行write操作了。
當進行write()操作的時候,資料是寫到Channel裡面了,但是緩衝器ByteBuffer裡面依然有資料,為了下次的read()操作,你應該clear()緩衝器裡的資料,使其內部指標重新安排。
c.)我們可以使用transferTo()和transferFrom()將一個通道和另一個通道連線。
d.)轉化資料:
緩衝器容納的是普通的位元組,為了把他們轉換成字元,要麼在輸入他們的時候進行編碼(為了輸出時有意義),也可以buffer.asCharBuffer().put(“String”),輸出的時候,buffer.asCharBuffer();即轉換成charBuffer存入取出資料(這裡有待理解)。
e.)獲取基本型別:
可以利用asCharBuffer()、asIntBuffer()等獲得該緩衝器上的檢視,然後呼叫put()方法向曲終填入資料。有一個小小特例,使用ShortBuffer的put()方法時,需要進行資料的轉換。 資料型別轉換會截圖或者改變結果。
f.)位元組存放次序:
位元組存放次序:1.big endian (高位優先) 將最重要的自己存放在地址最低的儲存單元。
2.little endian(低位優先) 與之相反。
我們可以使用帶有引數ByteOrder.BIG_ENDIAN或者ByteOrder.LITTLE_ENDIAN的order()方法來改變ByteBuffer的位元組排序方式。
Buffered bb;
Bb.order(ByteOrder.BIG_ENDIAN)
對於由輸出支援的緩衝期呼叫bb.array(),可以顯示檢視底層細節。
g.)我們不能把基本型別的緩衝器轉換成ByteBuffer,但是我們可以經由檢視緩衝器將基本型別資料移進移出ByteBuffer。
h.)關於緩衝器ByteBuffer的三個方法:flip(),clear(),remind()
一、flip():反轉此緩衝區,將限制設定為當前位置,然後將位置設定為 0 !
之前的寫操作會不斷更新當前位置,當寫操作完成之後,需呼叫此方法,將限制位置設定為當前位置,將當前位置設定為0,這樣下一個讀操作會從0開始,直到限制位置。
Java程式碼
1. /**
2. * Flips this buffer. The limit is set to the current position and then
3. * the position is set to zero. If the mark is defined then it is
4. * discarded.
5. *
6. * <p> This method is often used in conjunction with the {@link
7. * java.nio.ByteBuffer#compact compact} method when transferring data from
8. * one place to another. </p>
9. *
10. * @return This buffer
11. */
12. publicfinal Buffer flip() {
13. limit = position;
14. position = 0;
15. mark = -1;
16. returnthis;
17. }
/**
* Flips this buffer. The limit is set to the current position and then
* the position is set to zero. If the mark is defined then it is
* discarded.
*
* <p> This method is often used in conjunction with the {@link
* java.nio.ByteBuffer#compact compact} method when transferring data from
* one place to another. </p>
*
* @return This buffer
*/
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
Java程式碼
1. publicbyte get() {
2. return hb[ix(nextGetIndex())];
3. }
4.
5. finalint nextGetIndex() { // package-private
6. if (position >= limit)
7. thrownew BufferUnderflowException();
8. return position++;
9. }
public byte get() {
return hb[ix(nextGetIndex())];
}
final int nextGetIndex() {// package-private
if (position >= limit)
throw new BufferUnderflowException();
return position++;
}
二、rewind():與flip不同的是,不會修改限制位置。
比如初始化時:
Java程式碼
1. ByteBuffer buffer=ByteBuffer.allocate(1024);
ByteBuffer buffer=ByteBuffer.allocate(1024);
那麼做讀操作的時候就會讀到第(1024-1)個索引,而flip卻不一定能讀到(1024-1)個索引,這取決於他的寫操作的資料長度。
Java程式碼
1. /**
2. * Rewinds this buffer. The position is set to zero and the mark is
3. * discarded.
4. *
5. * <p> Invoke this method before a sequence of channel-write or <i>get</i>
6. * operations, assuming that the limit has already been set
7. * appropriately. For example:
8. *
9. * <blockquote><pre>
10. * out.write(buf); // Write remaining data
11. * buf.rewind(); // Rewind buffer
12. * buf.get(array); // Copy data into array</pre></blockquote>
13. *
14. * @return This buffer
15. */
16. publicfinal Buffer rewind() {
17. position = 0;
18. mark = -1;
19. returnthis;
20. }
/**
* Rewinds this buffer. The position is set to zero and the mark is
* discarded.
*
* <p> Invoke this method before a sequence of channel-write or <i>get</i>
* operations, assuming that the limit has already been set
* appropriately. For example:
*
* <blockquote><pre>
* out.write(buf); // Write remaining data
* buf.rewind(); // Rewind buffer
* buf.get(array); // Copy data into array</pre></blockquote>
*
* @return This buffer
*/
public final Buffer rewind() {
position = 0;
mark = -1;
return this;
}
三、clear():“清除”此緩衝區,將位置設定為 0,將限制設定為容量!此方法不能實際清除緩衝區中的資料,但從名稱來看它似乎能夠這樣做,這樣命名是因為它多數情況下確實是在清除資料時使用。因為呼叫該方法後,我們一般都會呼叫FileChannel.read(buff)或者buff.put()來把新的資料放到buff中,此時原來的內容就會被新的內容所覆蓋!也不是全部覆蓋,而是覆蓋掉新資料所包含的位元組數!所以看起來好象就是原來的內容被刪除一樣!
Java程式碼
1. /**
2. * Clears this buffer. The position is set to zero, the limit is set to
3. * the capacity, and the mark is discarded.
4. *
5. * <p> Invoke this method before using a sequence of channel-read or
6. * <i>put</i> operations to fill this buffer. For example:
7. *
8. * <blockquote><pre>
9. * buf.clear(); // Prepare buffer for reading
10. * in.read(buf); // Read data</pre></blockquote>
11. *
12. * <p> This method does not actually erase the data in the buffer, but it
13. * is named as if it did because it will most often be used in situations
14. * in which that might as well be the case. </p>
15. *
16. * @return This buffer
17. */
18. publicfinal Buffer clear() {
19. position = 0;
20. limit = capacity;
21. mark = -1;
22. returnthis;
23. }
/**
* Clears this buffer. The position is set to zero, the limit is set to
* the capacity, and the mark is discarded.
*
* <p> Invoke this method before using a sequence of channel-read or
* <i>put</i> operations to fill this buffer. For example:
*
* <blockquote><pre>
* buf.clear(); // Prepare buffer for reading
* in.read(buf); // Read data</pre></blockquote>
*
* <p> This method does not actually erase the data in the buffer, but it
* is named as if it did because it will most often be used in situations
* in which that might as well be the case. </p>
*
* @return This buffer
*/
public final Buffer clear() {
position = 0;
limit = capacity;
mark = -1;
return this;
}
四、ByteBuffer類中提供position(),remaining(),hasRemaining(),limit()等方法來驗證以上三點。
五、上述程式碼中提到的:
Java程式碼
1. and the mark is discarded.
and the mark is discarded.
i.)緩衝器細節:
mark標記 position位置 capacity容量 limit 限制
capacity(),
clear()-----這個方法並不是真正的刪除資料,而是覆蓋資料,覆蓋的長度由新資料長度決定
filp()
limit()
limit(int) 設定limit值
mark()
position(int pos)設定position值
remaining()返回limit - position
hasRemaining()
j.)緩衝器妙用:
當呼叫put()和get()方法的時候,position指標就會改變,但是當你呼叫包含索引的get()和put()方法,索引的位置不會發生變化。
mark()方法用來設定mark()的值,reset()方法把potiostion的值設為mark的值。
個人理解:緩衝器是一個很好的資料承載結構,它有4個特性,mark標記 position位置 capacity容量 limit 限制,通過還有上述的改變postion的get()和put()方法以及不改變遊標的get()和put()方法,有reset()和mark()方法等等,我們可以很方便的移動資料,我們可以改變緩衝器中資料的排列順序(比如臨近的char互換),因此,個人理解,緩衝期是一個很好的資料承載結構。
k.)記憶體對映檔案:
獲得Channel之後可以通過map()方法產生MappeByteBuffer(Mode,int from ,int to),生成MappedByteBuffer的時候必須指定對映檔案的初始位置和對映區域的長度,這意味著我們可以對映某個大檔案的較小的部分。對映檔案速度很快。
l.)檔案加鎖:
無參形式的tryLock()和lock()可以獲得整個檔案的FileLock()。
tryLock()和lock()的區別:
tryLock()是非阻塞式的,它”設法”獲取鎖,但是如果不能獲得,他將直接從方法呼叫返回。
lock()是阻塞式的,他要阻塞程序直至鎖可以獲得,或者lock()的執行緒中斷,要麼呼叫lock()的通道關閉。
也可以tryLock(long position ,long size ,boolean shared)或者
lock(long position,long size ,boolean shared)
加鎖的區域由size-poition決定,第三個引數指定是否是共享鎖。
無引數的加鎖方法根據檔案的尺寸的變化而變化,但是具有固定尺寸的鎖不隨檔案的尺寸的變化而變化。檔案變化的時候,無參鎖會對整個檔案進行加鎖。
鎖的型別:共享鎖和獨佔鎖的支援必須由底層的作業系統支援。如果作業系統不支援共享鎖併為每一個請求加一個鎖,那麼會使用獨佔鎖。
FileLock.isShared()可以查詢鎖的型別。
檔案對映通常應用於極大的檔案,我們可能需要對這種巨大的檔案加鎖,以便其他程序可以修改檔案中違背加鎖的部分。
我們不能得到緩衝器上的鎖,只能獲得通道上的鎖。
11.壓縮:
壓縮類庫是按位元組而不是按字元方式處理的,所以它屬於InputStreamhe 和OutputStream繼承層次結構。但是有時候會和Reader和Writer混合使用。
a.)壓縮類:
ChcekedInputStream---GetChecmSum()
ChcekedOutputStream
DeflaterOutputStream------壓縮類的基類
ZipOutputStream
GZIPOutputStream
InflaterInputStream------解壓類的基類
ZipInputStream
ZIPInputStream
壓縮類構造器只接受 In/OutputStream
b.)方法:
BufferedReader b = new BufferedReader(new FileReader("d://abc.txt"));
File file = new File("d://data.zip");
ZipOutputStream zo = new ZipOutputStream(new
1.File:
a.) FilenameFilter:
class DirFilter implementsFilenameFilter{
private Pattern pattern;
public DirFilter(String args)
CharArrayWriter介紹
用於寫入字元資料,繼承於writer,操作的是單位為字元。
原始碼分析
CharArrayWriter
package java.io;
import java.util.Arrays;
public class C
CharArrayReader介紹
CharArrayReader是字元輸入流,用於讀取字元陣列,它繼承於Reader,操作的資料是字元為單位。
原始碼分析
Reader是CharArrayReader的父類,我們先看一下Reader的原始碼,然後再分析Cha
BufferedInputStream介紹
BufferedInputStream是緩衝輸入流,作用是為另外一個輸入流新增緩衝功能,以及mark reset功能。
本質上,緩衝功能是通過一個內部緩衝區陣列實現的,例如在新建某輸入流對應的BufferedInputStream後,
介紹
PrintWriter 是字元型別的列印輸出流,它繼承於Writer。
PrintWriter用於向文字輸出流列印物件的格式化表示形式。它實現在 PrintStream 中的所有 print 方法。
原始碼
package jav
介紹
BufferedWriter 是緩衝字元輸出流。它繼承於Writer。 BufferedWriter 的作用是為其他字元輸出流新增一些緩衝功能。
原始碼分析
package java.io;
public class BufferedWriter ex
InputStreamReader和OutputStreamWriter介紹
InputStreamReader和OutputStreamWriter是位元組通往字元的橋樑,它使用指定的charset讀取位元組並將其解碼為字元。
InputStreamReader的作用是將位元
PipedReader和PipedWriter介紹
PipedWriter是字元管道輸出流,繼承於Writer
PipedReader是字元管道輸入流,繼承於Reader
PipedReader和PipedWriter的作用是可以通過管道之間進行執行緒間的通訊,
PrintStream介紹
PrintStream是列印輸出流,繼承自FilterOutputStream,PrintStream用來裝飾其他的流,為其他流新增列印功能,使其能夠方便列印各種資料表現形式。
與其他流不同,PrintStream永遠不會丟擲IOException,
BufferOutputStream介紹
BufferOutputStream是緩衝輸出流,它繼承於FilterOutputStream。
BufferOutputStream的作用是另一個輸出流提供“緩衝功能”。
原始碼分析
package java.i
序列化的作用和用途
序列化,就是為了保持物件的狀態,而與之對應的反序列化,則可以把物件的狀態再讀取出來,
簡而言之:序列化/反序列化,是JAVA提供的一種專門用於儲存/恢復物件狀態的機制。
一般在以下幾種情況我們會使用序列化:
1.當你想把記憶體中的物件狀態儲存到
Map框架圖
Map概括
Map是鍵值對對映的抽象介面
AbstractMap實現了Map中的大部分介面,減少了Map實現類的重複程式碼
HashMap是基於拉鍊法實現的散列表,一般使用在單執行緒程式中
HashTable是基於拉鍊法
get()方法
獲取key相對應的value,實現程式碼如下
public V get(Object key) {
if (key == null)
return getForNullKey();
// 獲取key的hash值
int has
緩衝思想
位元組流一次讀寫一個數組的速度明顯比一次讀寫一個位元組的速度快很多,這是加入了陣列這樣的緩衝區的效果。
BufferedInputStream
BufferedInputStream中讀取一個緩衝區(陣列),從BufferedInputStream中讀
1.IO流中還包含了其他流,如下:
2..資料操作流(操作基本型別資料的流)
(1)可以操作基本型別的資料
(2)流物件名稱
DataInputStream
DataOutputSt
輸入輸出的重要性:
輸入和輸出功能是Java對程式處理資料能力的提高,Java以流的形式處理資料。流是一組有序的資料序列,根據操作的型別,分為輸入流和輸出流。
程式從輸入流讀取資料,向輸出流寫入資料。Java是面向物件的程式語言,每一個數
1.File類 File類可以在程式中 操作檔案和目錄。File類是通過建立File類物件,在呼叫File類的物件來進行相關操作的。 示例: --------------------- 本文來自 dajiahuooo 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/
1.使用字元流複製檔案的5種方法
package com.dml.io2;
/**
* 使用字元流的方法複製檔案
*/
import java.io.BufferedReader;
import java.io.BufferedWriter;
import
這次總結以用法為主,涉及的深入原理暫不理會
1 繼承於InputStream的常用輸入流 (1). 檔案輸入流FileInputStream (2). 管道輸入流PipedInputStream (3). 緩衝輸入流BufferedInputStream (4). 合併輸入流Se
FileDescriptor簡介
FileDescriptor是檔案描述符
FileDescriptor可以被用來表示開放檔案,開放套接字等
以FileDescriptor表示檔案來說,當FileDescriptor表示某檔案的時候,我們可以通俗地將FileDescript 相關推薦
Thinking In Java----2017.1.29 IO流(完結版,乾貨)
thinking in java (二十七) ----- IO之CharArrayWriter(字元陣列輸出流)
thinking in java (二十七) ----- IO之CharArrayReader(字元陣列輸入流)
thinking in java (二十四) ----- IO之BufferedInputStream
thinking in java (三十二) ----- IO之 PrintWriter
thinking in java (三十一) ----- IO之 BufferedWriter
thinking in java (二十九) ----- IO之 InputStreamReader和OutputStreamWriter
thinking in java (二十八) ----- IO之PipedReader和PipedWriter
thinking in java (二十五) ----- IO之PrintStream
thinking in java (二十四) ----- IO之BufferedOutputStream
thinking in java (二十二) ----- IO之序列化
thinking in java (十八) ----- 集合之Map(HashMap HashTable)總結
thinking in java (十六) ----- 集合之HahsMap(之二)
java輸入輸出13:IO流(BufferedInputStream和BufferedOutputStream拷貝)
Java基礎知識 十三 IO流(下)
Java實現檔案寫入——IO流(輸入輸出流詳解)
IO流(File類,IO流的分類,位元組流和字元流,轉換流,緩衝流,物件序列化)
IO流(檔案複製的方法)
Thinking in java自讀筆記:常用輸入輸出流
thinking in java (二十三) ----- IO之FileDescriptor