[Java開發之路](8)輸入流和輸出流
阿新 • • 發佈:2019-01-17
1. Java流的分類 按流向分: 輸入流: 可以從其中讀入一個位元組序列的物件稱作輸入流。 輸出流: 可以向其中寫入一個位元組序列的物件稱作輸出流。 這些位元組序列的來源地和目的地可以是檔案,而且通常都是檔案,但是也可以是網路連線,甚至是記憶體塊。抽象類InputStream和OutputStream構成了輸入和輸出類層結構的基礎。 按資料傳輸單位分: 位元組流: 以位元組為單位傳輸資料的流 字元流: 以字元為單位傳輸資料的流 按功能分: 節點流: 用於直接操作目標裝置的流 過濾流: 是對一個已存在的流的連結和封裝,通過對資料進行處理為程式提供功能強大、靈活的讀寫功能。 2. 讀寫位元組(
abstractint read()
這個方法將讀入一個位元組,並返回讀入的位元組,或者在遇到輸入源結尾時返回-1。在設計具體的輸入流時,必須覆蓋這個方法以提供適用的功能,例如,在FileInputStream類中,這個方法將從某個檔案中讀入一個位元組。
InputStream類還有若干個非抽象的方法,它們可以讀入一個位元組陣列,或者跳過大量的位元組。這些方法都要呼叫抽象的read方法,因此各個子類都只需覆蓋一個方法。
(2)OutputStream類定義了下面的抽象方法:
abstract void write(int b)
它可以向某個輸出位置寫出一個位元組。
(3)read和write方法在執行時都將阻塞,直至位元組確實被讀入或寫出。這就意味著如果流不能被立即訪問(通常因為網路連線忙),那麼當前的執行緒將被阻塞。這使得在這兩個方法等待指定流變為可用的這段時間內,其他的執行緒就有機會去執行有用的工作。
當你完成對流的讀寫時,應該通過呼叫close方法來關閉它,這個呼叫會釋放掉十分有限的作業系統資源。如果一個應用程式打開了過多的流而沒有關閉,那麼系統資源將被耗盡。關閉一個輸出流的同時還會沖刷用於該輸出流的緩衝區:所有被臨時置於緩衝區中,以便用更大的包的形式傳遞的字元在關閉輸出流時都將被送出輸入/輸出 | 位元組流 | 字元流 |
輸入流 | InputStream | Reader |
輸出流 | OutputStream | Writer |
4.1 InputStream抽象類 InputStream 為位元組輸入流,它本身為一個抽象類,必須依靠其子類實現各種功能,此抽象類是表示位元組輸入流的所有類的超類。 繼承自InputStream 的流都是向程式中輸入資料的,且資料單位為位元組(8bit);
InputStream是輸入位元組資料用的類,所以InputStream類提供了3種過載的read方法。Inputstream類中的常用方法:
常用方法 | 描述 |
public abstract int read( ) | 從輸入流中讀取下一個位元組資料。返回位元組使用高位補0的int型別值表示(0-255),若返回值為-1說明沒有讀取到任何位元組,輸入流達到盡頭。 |
public int read(byte b[ ]) | 從輸入流中讀取b.length個位元組的資料放到位元組陣列b中。返回值是讀取的位元組數。如果位元組陣列的長度為0,不會讀取任何位元組資料,返回0,否則至少嘗試去讀取一個位元組的資料。如果沒有獲取到位元組資料,表示流到達檔案末尾,返回-1。第一個讀取的位元組儲存在b[0],以此類推。 |
public int read(byte b[ ], int off, int len) | 從輸入流中讀取至多len個位元組的資料放到位元組陣列b中。返回值是讀取的實際位元組數。如果位元組陣列的長度為0,不會讀取任何位元組資料,返回0,否則至少嘗試去讀取一個位元組的資料。如果沒有獲取到位元組資料,表示流到達檔案末尾,返回-1。第一個讀取的位元組儲存在b[off],下一個儲存在b[off+1],以此類推。 |
public int available( ) | 返回輸入流中可以讀取的位元組數。注意:若輸入阻塞,當前執行緒將被掛起,如果InputStream物件呼叫這個方法的話,它只會返回0,這個方法必須由繼承InputStream類的子類物件呼叫才有用。注意:雖然很多InputStream的實現類可以正確的返回輸入流的總位元組數,但是並不是全都都可以。所以使用這個方法的返回值去分配位元組大小來容納輸入流的所有資料一定不是一個正確的方法。 |
public long skip(long n) | 忽略輸入流中的n個位元組,返回值是實際忽略的位元組數, 如果為負數,表示沒有跳過任何位元組資料。 |
public int close( ) | 關閉輸入流,釋放分配給輸入流的系統資源。 |
InputStream的作用是用來表示那些那些從不同資料來源產生輸入的類。這些資料來源包括:
- 位元組陣列
- String物件
- 檔案
- "管道",工作方式與實際管道相似,從一端進入,從一端輸出
- 一個由其他種類的流組成的序列,以便我們可以將它們收集合併到一個流內
類 | 功能 |
ByteArrayInputStream | 允許將記憶體中緩衝區當做InputStream使用 |
StringBufferInputStream | 將String轉換成InputStream |
FileInputStream | 用於從檔案中讀取資訊 |
PipedInputStream | 產生用於寫入相關PipedOutputStream的資料。實現“管道化”概念。 |
SequenceInputStream | 將兩個或者多個InputStream物件轉換成單一InputStream |
FilterInputStream | 抽象類,作為“裝飾器”的介面。其中,“裝飾器”為其他的InputStream類提供有用的功能。 |
常用方法 | 描述 |
public abstract void write(int b) | 將指定位元組寫入到輸出流中。一般是將引數b的低八位(一個位元組)寫入到輸出流中。b的高八位被忽略掉。 |
public void write(byte[] b) | 從位元組陣列b中向輸出流中寫入b.length個位元組資料。 |
public void write(byte[] b,int off,int len) | 從位元組陣列b偏移位置為off的開始位置向輸出流寫入len個位元組資料。b[off]是第一個被寫入的位元組,b[off+len-1]是最後一個被寫入的位元組。如果b為null,會丟擲NullPointer異常;如果off或者len是負數,或者off+len比位元組陣列b的長度大,則會丟擲IndexOutOfBoundsException異常。 |
public void flush() | 清空輸出流,並強制將所有緩衝的輸出位元組被寫出。 |
public void close() | 關閉輸出流,釋放分配給輸出流的系統資源。 |
該類別的類決定了輸出所要去往的目標:位元組陣列(但不是String,不過你當然可以使用位元組陣列自己來建立),檔案或管道。
類 | 功能 |
ByteArrayOutputStream | 在記憶體中建立緩衝區,所有送往“流”的資料都要放置在此緩衝區。 |
FileOutputStream | 用於將資訊寫至檔案。 |
PipedOutputStream | 任何寫入其中的資訊都會自動作為PipedInputStream的輸出。實現“管道化”概念。 |
FilterOutputStream | 抽象類,作為“裝飾器”的介面。其中,“裝飾器”為其他的OutputStream類提供有用的功能。 |
Writer的子類:
6. FileInputStream和FileOutputStream 6.1 FileInputStream
FileInputStream 從檔案系統中的某個檔案中獲得輸入位元組。
(1)構造方法
構造方法 | 描述 |
FileInputStream(String name) | 使用由name字串指定路徑名檔案建立FileInputStream物件 |
FileInputStream(File file) | 使用由file物件指定路徑名的檔案建立FileInputStream物件 |
// FileInputStream(String name)
String path ="D:\\Recommended system.txt";
FileInputStream stream =newFileInputStream(path);
// FileInputStream(File file)
File file =newFile(path);
FileInputStream stream2 =newFileInputStream(file);
(2)說明
- 用於讀取諸如影象資料之類的原始位元組流。(要讀取字元流,請考慮使用 FileReader)
- 包含其他一些輸入流,它將這些流用作其基本資料來源,它可以直接傳輸資料或提供一些額外的功能。
- 類本身只是簡單地重寫那些將所有請求傳遞給所包含輸入流的 InputStream 的所有方法。
- 其子類可進一步重寫這些方法中的一些方法,並且還可以提供一些額外的方法和欄位。
package com.qunar.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
publicclassIOUtil{
publicstaticvoid main(String[] args){
try{
String path ="D:\\demo.txt";
FileInputStream stream =newFileInputStream(path);
int num =100;
byte[] buff =newbyte[num];
while((stream.read(buff,0,num))!=-1){
System.out.println("NewLine->"+newString(buff));
}//while
stream.close();
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
}
執行結果:
NewLine->My father was a self-taught mandolin player. He was one of the best string instrument players in our NewLine-> town. He could not read music, but if he heard a tune a few times, he could play it. When he was yo NewLine->unger, he was a member of a small country music band. They would play at local dances and on a NewLine->ccasions would play for the local radio station. He often told us how he had auditioned and earned a NewLine-> position in a band that featured Patsy Cline as their lead singer. He told the family that after he NewLine-> was hired he never went back. Dad was a very religious man. He stated that there was a lot of drink NewLine->ing and cursing the day of his audition and he did not want to be around that type of environment.nk |
(1)建構函式
建構函式 | 描述 |
FileOutputStream(String name) | 使用由name字串指定路徑名的檔案建立一個新的檔案輸出流。 |
FileOutputStream(String name,boolean append) | 使用由name字串指定路徑名的檔案建立一個新的檔案輸出流。如果append引數為true,那麼資料將被新增到檔案末尾,而具有相同名字的已有檔案不會被刪除(末尾新增資料);否則這個方法刪除所有具有相同名字的已有檔案。 |
FileOutputStream(File file) | 使用由file物件指定路徑名的檔案建立一個新的檔案輸出流。 |
FileOutputStream(File file,boolean append) | 使用由file物件指定路徑名的檔案建立一個新的檔案輸出流。如果append引數為true,那麼資料將被新增到檔案末尾,而具有相同名字的已有檔案不會被刪除(末尾新增資料);否則這個方法刪除所有具有相同名字的已有檔案。 |
package com.qunar.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
publicclassIOUtil{
publicstaticvoid main(String[] args){
try{
String path ="D:\\from.txt";
String path2 ="D:\\to.txt";
FileInputStream inputStream =newFileInputStream(path);
FileOutputStream outputStream =newFileOutputStream(path2);
int num =100;
byte[] buff =newbyte[num];
// 由檔案寫至記憶體
while((inputStream.read(buff,0,num))!=-1){
// 由記憶體寫至檔案中
outputStream.write(buff);
}//while
inputStream.close();
outputStream.close();
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
<