### 一、流的概念
流是一系列有順序的字節的集合,是網絡傳輸的載體,流可以包裝成基本數據類型或對象,流有輸入和輸出,輸入時是從流從數據源流向程序輸出時是流從程序傳向數據源,而數據源可以是內存,文件,網絡或程序等,下面是流的輸入和輸出的圖形化:

### 二、流的分類
**(1)、流有字節流,字符流,輸入流和輸出流等。**
- 根據處理方向不同可分為:輸入流和輸出流。
- 根據處理數據類型不同可分為:字節流和字符流。
字節流和字符流的處理原理是相同的,只是處理的數據類型不同。
字節流是以字節為單位來傳輸,一個字節是8bit;
字符流是以字符為單位來傳輸,一個字符是16bit。
- 根據分工的不同可分為:節點流和處理流
**(2)、java I/O流基本類有**
字節流的抽象基類:
InputStream(字節輸入流),OutputStream(字節輸出流)
字符流的抽象基類:
Reader(字符輸入流),writer(字符輸出流)
其他類都由這4個抽象基本派生出來,詳細的流的類圖結構如下:

### 三、輸入和輸出流
**(1)、輸入可使用:**
1.InputStream – 一個字節一個字節(byte)地從數據源讀取。
*讀取一個字節并以整數的形式返回(0~255),如果返回-1已到輸入流的末尾。
int read() ;
*讀取一系列字節并存儲到一個數組buffer,返回實際讀取的字節數,如果讀取前已到輸入流的末尾返回-1。
int read(byte[] buffer) ;
*讀取length個字節并存儲到一個字節數組buffer,從off位置開始存,最多len, 返回實際讀取的字節數,如果讀取前以到輸入流的末尾返回-1。
int read(byte[] buffer, int off, int len) ;
*關閉流釋放內存資源。
void close() ;
2.Reader – 一個字符一個字符(char)地從數據源讀取。
*讀取一個字符并以整數的形式返回(0~255),如果返回-1已到輸入流的末尾。
int read() ;
*讀取一系列字符并存儲到一個數組buffer,返回實際讀取的字符數,如果讀取前已到輸入流的末尾返回-1。
int read(char[] cbuf) ;
*讀取length個字符,并存儲到一個數組buffer,從off位置開始存,最多讀取len,返回實際讀取的字符數,如果讀取前以到輸入流的末尾返回-1。
int read(char[] cbuf, int off, int len)
*關閉流釋放內存資源。
void close()
**(2)、輸入流可使用**
1.OutputStream:
*向輸出流中寫入一個字節數據,該字節數據為參數b的低8位。
void write(int b) ;
*將一個字節類型的數組中的數據寫入輸出流。
void write(byte[] b);
*將一個字節類型的數組中的從指定位置(off)開始的,len個字節寫入到輸出流。
void write(byte[] b, int off, int len);
*關閉流釋放內存資源。
void close();
*將輸出流中緩沖的數據全部寫出到目的地。
void flush();
2.Writer:
*向輸出流中寫入一個字符數據,該字節數據為參數b的低16位。
void write(int c);
*將一個字符類型的數組中的數據寫入輸出流,
void write(char[] cbuf) throws IOException
*將一個字符類型的數組中的從指定位置(offset)開始的,length個字符寫入到輸出流。
void write(char[] cbuf, int offset, int length);
*將一個字符串中的字符寫入到輸出流。
void write(String string);
*將一個字符串從offset開始的length個字符寫入到輸出流。
void write(String string, int offset, int length);
*關閉流釋放內存資源。
void close() throws IOException
*將輸出流中緩沖的數據全部寫出到目的地。
void flush() throws IOException
### 四、讀寫文本文件
**(1).寫文本文件**
1.FileWriter是繼承writer類,可調用write()方法往文本中寫入內容。下面程序為調用FileWriter類的write(type c)方法的實現:
~~~
String fileName="d:\\demo1.txt";
FileWriter write=new FileWriter(fileName);
write.write("hell,io\n");
write.write("welcome to study\n");
write.write("加油,謝謝!");
write.close();
~~~
2.BufferedWriter類是帶緩沖區的,比FileWriter要高效些,若寫入的內容多優先使用此類,此類有一個newLine()方法,可換行。
下面程序為BufferedWriter類write(type c)方法的實現:
~~~
//處理內容較多的數據是,用BufferedWriter更高效
BufferedWriter bWrite=new BufferedWriter(new FileWriter(fileName));
bWrite.write("hell,io");
bWrite.newLine();
bWrite.write("welcome to study");
bWrite.newLine();
bWrite.write("加油,謝謝!");
bWrite.close();
~~~
不論使用哪種方式,結束時都需要close()關閉流,否則會導致資源耗盡問題。
**(2).讀文本文件**
1.FileReader類是從文本文件讀取字符,下面代碼為FileReader類讀取文本文件的實現,返回的是一個int類型數。若讀取到末尾,則返回-1,下面為具體的實現:
~~~
FileReader read=new FileReader(fileName);
int len=read.read();
while(len!=-1){
System.out.println("len:"+len);
}
~~~
2.BufferedReader類是文本文件讀取的緩存器類,調用readLine()方法,可一行一行的讀取出整行字符,若讀取到末尾返回null,下面為具體的實現:
~~~
BufferedReader read=new BufferedReader(new FileReader(fileName));
String line=read.readLine();
while(line!=null){
System.out.println("line:"+line);
line=read.readLine();
}
read.close();
~~~
同時不論使用哪種方式,結束時都需要調用close()關閉流,否則會導致資源耗盡問題.
### 五、讀寫二進制數據
對于純文本文件里的內容都可解釋為字符,可以用Reader和writer進行讀寫,但對于那些圖片,聲音的不是純文本的內容,則需要利用二進制的字節方式進行讀寫,利用二進制字節讀取數據要比字符快,且編碼問題小。
**(1).寫二進制字節數據**
FileOutputStream類:用于字節的輸出;DataOutputStream類:用于將數據寫到另一個輸出流。下面為具體的實現:
~~~
DataOutputStream out =new DataOutputStream(new FileOutputStream(fileName));
out.writeInt(1);
out.writeDouble(11.20);
out.writeUTF("test");
out.close();
~~~
**(2).讀二進制文件**
通過另外一個流來構造一個過濾流,常用的子類有
DataInputStream 和 BufferedInputStream。后者是將字節數據讀取到緩沖區.相對要高效些。下面為具體的實現:
~~~
String fileName="d:\\demo.dat";
DataInputStream in=new DataInputStream(new BufferedInputStream(new FileInputStream(fileName)));
System.out.println(in.readInt()+"-"+in.readDouble()+"-"+in.readUTF());
in.close();
~~~
還有幾個特殊的類,如:
LineNumberInputStream:構造一個讀取指定的輸入流的輸入??的新行號輸入流。
PushbackInputStream:構建一個可預覽一個字節或具有指定尺寸的緩沖區的流。
總結:本文主要分析了流的作用,流的分類,流的類圖結構以及流的一些操作,比較基礎,下篇將介紹流的文件管理,文檔的壓縮和對象序列化等操作。