Ⅰ java中流的種類,按功能和內容分別介紹
1、從功能上:輸入流、輸出流。
輸入流就是從外部輸入數據到程序,輸出流就是從程序輸出數據到外部。
外部就是只硬碟、資料庫、網路等。
2、從結構上:位元組流、字元流。
位元組流是操作位元組集的,字元流是操作字元串的。
字元串轉換為位元組集也可以通過位元組流進行傳輸。
3、從來源上:節點流、過濾流。
節點流好像也叫原始流,過濾流好像也叫裝飾流,不記得了。
過濾流操作的本質也是節點流,就像List的本質是數組一樣。
這個很抽象,你學了就知道。
不行你就再網路一下吧。
Ⅱ java io流的典型使用方式有幾種
Java中IO流分成兩大類,
一種是輸入流,所有的輸入流都直接或間接繼承自InputStream抽象類,輸入流作為數據的來源,我們可以通過輸入流的read方法讀取位元組數據;
另一種是輸出流,所有的輸出流都直接或間接繼承自OutputStream抽象類,輸出流接收數據,可以通過write方法寫入位元組數據。
Java的IO流類中,大部分的輸入流和輸出流都是成對存在的,即如果存在XXXInputStream,那麼就存在XXXOutputStream,反之亦然。SequenceInputStream和StringBufferInputStream是特例,沒有對應的SequenceOutputStream類和StringBufferOutputStream類,許多IO操作都可能會拋出IOException異常,比如read、write、close操作。
以下是Java的IO流中常見的輸入流,由於每個輸入流都有其對應的輸出流,所以此處就不再列出輸出流的繼承結構圖。
1、ByteArrayInputStream & ByteArrayOutputStream:
ByteArrayInputStream構造函數中需要傳入一個byte數組作為數據源,當執行read操作時,就會從該數組中讀取數據,正如其名,是一種基於位元組數組實現的一種簡單輸入流,顯而易見的是,如果在構造函數中傳入了null作為位元組數據,那麼在執行read操作時就會出現NullPointerException異常,但是在構造函數初始化階段不會拋出異常;與之相對應的是ByteArrayOutputStream,其內部也有一個位元組數組用於存儲write操作時寫入的數據,在構造函數中可以傳入一個size指定其內部的byte數組的大小,如果不指定,那麼默認它會將byte數組初始化為32位元組,當持續通過write向ByteArrayOutputStream中寫入數據時,如果其內部的byte數組的剩餘空間不能夠存儲需要寫入的數據,那麼那麼它會通過調用內部的ensureCapacity
方法對其內部維護的byte數組進行擴容以存儲所有要寫入的數據,所以不必擔心其內部的byte數組太小導致的IndexOutOfBoundsException之類的異常。
2、FileInputStream & FileOutputStream
FileInputStream 能夠將文件作為數據源,讀取文件中的流,通過File對象或文件路徑等初始化,在其構造函數中,如果傳入的File對象(或與其相對應的文件路徑所表示的File對象)不存在或是一個目錄而不是文件或者由於其他原因無法打開讀取數據,都會導致在初始化階段導致拋出FileNotFoundException異常;與FileInputStream 相對應的是FileOutputStream,可以通過FileOutputStream向文件中寫入數據,也需要通過File對象或文件路徑對其初始化,如同FileInputStream ,如果傳入的File對象(或與其相對應的文件路徑所表示的File對象)是一個目錄而不是文件或者由於其他原因無法創建該文件寫入數據,都會導致在初始化階段拋出FileNotFoundException異常。
3、PipedInputStream & PipedOutputStream
PipedInputStream和PipedOutputStream一般是結合使用的,這兩個類用於在兩個線程間進行管道通信,一般在一個線程中執行PipedOutputStream 的write操作,而在另一個線程中執行PipedInputStream的read操作。可以在構造函數中傳入相關的流將PipedInputStream 和PipedOutputStream 綁定起來,也可以通過二者的connect方法將二者綁定起來,一旦二者進進行了綁定,那麼PipedInputStream的read方法就會自動讀取PipedOutputStream寫入的數據。PipedInputStream的read操作是阻塞式的,當執行PipedOutputStream的write操作時,PipedInputStream會在另一個線程中自動讀取PipedOutputStream寫入的內容,如果PipedOutputStream一直沒有執行write操作寫入數據,那麼PipedInputStream的read方法會一直阻塞PipedInputStream的read方法所運行的線程直至讀到數據。單獨使用PipedInputStream或單獨使用PipedOutputStream時沒有任何意義的,必須將二者通過connect方法(或在構造函數中傳入對應的流)進行連接綁定,如果單獨使用其中的某一個類,就會觸發IOException: Pipe Not Connected.
4、ObjectInputStream & ObjectOutputStream
ObjectOutputStream具有一系列writeXXX方法,在其構造函數中可以摻入一個OutputStream,可以方便的向指定的輸出流中寫入基本類型數據以及String,比如writeBoolean、writeChar、writeInt、writeLong、writeFloat、writeDouble、writeCharts、writeUTF等,除此之外,ObjectOutputStream還具有writeObject方法。writeObject方法中傳入的類型必須實現了Serializable介面,從而在執行writeObject操作時將對象進行序列化成流,並將其寫入指定的輸出流中。與ObjectOutputStream相對應的是ObjectInputStream,ObjectInputStream有與OutputStream中的writeXXX系列方法完全對應的readXXX系列方法,專門用於讀取OutputStream通過writeXXX寫入的數據。
5、SequenceInputStream
SequenceInputStream 主要是將兩個(或多個)InputStream在邏輯上合並為一個InputStream,比如在構造函數中傳入兩個InputStream,分別為in1和in2,那麼SequenceInputStream在讀取操作時會先讀取in1,如果in1讀取完畢,就會接著讀取in2。在我們理解了SequenceInputStream 的作用是將兩個輸入流合並為一個輸入流之後,我們就能理解為什麼不存在對應的SequenceOutputStream 類了,因為將一個輸出流拆分為多個輸出流是沒有意義的。
6、StringBufferInputStream
StringBufferInputStream允許通過在構造函數中傳入字元串以讀取位元組,在讀取時內部主要調用了String的charAt方法。與SequenceInputStream類似,StringBufferInputStream也沒有對應的OutputStream,即不存在StringBufferOutputStream類。Java沒有設計StringBufferOutputStream類的理由也很簡單,我們假設StringBufferOutputStream存在,那麼StringBufferOutputStream應該是內部通過執行write操作寫入數據更新其內部的String對象,比如有可能是通過StringBuilder來實現,但是這樣做毫無意義,因為一旦我們String的構造函數中可以直接傳入位元組數組構建字元串,簡單明了,所以設計StringBufferOutputStream就沒有太大的必要了。StringBufferInputStream這個類本身存在一點問題,它不能很好地將字元數組轉換為位元組數組,所以該類被Java標記為廢棄的(Deprecated),其官方推薦使用StringReader作為代替。
7、FilterInputStream & FilterOutputStream
FilterInputStream包含了其他的輸入流,說具體點就是在其構造函數中需要傳入一個InputStream並將其保存在其名為in的欄位中,FilterInputStream只是簡單的覆蓋了所有的方法,之所說是簡單覆蓋是因為在每個覆蓋函數中,它只是調用內部的保存在in欄位中的InputStream所對應的方法,比如在其覆蓋read方法時,內部只是簡單調用了in.read()方法。FilterInputStream的子類可以進一步覆蓋某些方法以保持介面不變的情況下實現某一特性(比如其子類有的可以通過使用緩存優化讀取的效率)或者提供一些其他額外的實用方法。所以在使用時FilterInputStream可以讓傳入的InputStream具有一些額外的特性,即對構造函數傳入的InputStream進行了一層包裹,使用了典型的裝飾著模式,如果只看FilterInputStream本身這一個類的話,則該類自己本身意義不大,因為其只是通過內部的欄位in簡單覆寫某些方法。但是如果將FilterInputStream 和其子類結合起來使用話,那麼就很有用了。比如FilterInputStream 有兩個子類BufferedInputStream和DataInputStream,這兩個類在下面還會詳細介紹。BufferedInputStream對read操作做了優化,每次讀操作時都讀取一大塊數據,然後將其放入內部維護的一個位元組數組緩沖區中。當外面調用BufferedInputStream的read方法時,首先去該緩沖區中讀取數據,這樣就避免了頻繁的實際的讀操作,BufferedInputStream對外沒有暴露額外的其他方法,但是其內部的read方法已經經過優化了,所以在執行讀操作的時候效率更高。DataInputStream與ObjectInputStream有點類似,可以通過一些readXXX方法讀取基本類型的數據,這是非常有用的一些方法。
8、BufferedInputStream & BufferedOutputStream
如上面所介紹的那樣,在BufferedInputStream的構造函數中需要傳入一個InputStream, BufferedInputStream內部有一個位元組數組緩沖區,每次執行read操作的時候就從這buf中讀取數據,從buf中讀取數據沒有多大的開銷。如果buf中已經沒有了要讀取的數據,那麼就去執行其內部綁定的InputStream的read方法,而且是一次性讀取很大一塊數據,以便填充滿buf緩沖區。緩沖區buf的默認大小是8192位元組,也就是8K,在構造函數中我們也可以自己傳入一個size指定緩沖區的大小。由於我們在執行BufferedInputStream的read操作的時候,很多時候都是從緩沖區中讀取的數據,這樣就大大減少了實際執行其指定的InputStream的read操作的次數,也就提高了讀取的效率。與BufferedInputStream 相對的是BufferedOutputStream。在BufferedOutputStream的構造函數中我們需要傳入一個OutputStream,這樣就將BufferedOutputStream與該OutputStream綁定在了一起。BufferedOutputStream內部有一個位元組緩沖區buf,在執行write操作時,將要寫入的數據先一起緩存在一起,將其存入位元組緩沖區buf中,buf是有限定大小的,默認的大小是8192位元組,即8KB,當然也可以在構造函數中傳入size指定buf的大小。該buf只要被指定了大小之後就不會自動擴容,所以其是有限定大小的,既然有限定大小,就會有被填充完的時刻,當buf被填充完畢的時候會調用BufferedOutputStream的flushBuffer方法,該方法會通過調用其綁定的OutputStream的write方法將buf中的數據進行實際的寫入操作並將buf的指向歸零(可以看做是將buf中的數據清空)。如果想讓緩存區buf中的數據理解真的被寫入OutputStream中,可以調用flush方法,flush方法內部會調用flushBuffer方法。由於buf的存在,會大大減少實際執行OutputStream的write操作的次數,優化了寫的效率。
Ⅲ java的幾種IO流讀取文件方式
一、超類:
位元組流: InputStream(讀入流) OutputStream(寫出流)
字元流: Reader(字元 讀入流) Writer (字元寫出流)
二、文件操作流
位元組流: FileInputStream ,FileOutputStream
字元流: FileReader, FileWriter(用法與位元組流基本相同,不寫)
//1.指定要讀 的文件目錄及名稱
File file =new File("文件路徑");
//2.創建文件讀入流對象
FileInputStream fis =new FileInputStream(file);
//3.定義結束標志,可用位元組數組讀取
int i =0 ;
while((i = fis.read())!=-1){
//i 就是從文件中讀取的位元組,讀完後返回-1
}
//4.關閉流
fis.close();
//5.處理異常
//1.指定要寫到的文件目錄及名稱
File file =new File("文件路徑");
//2.創建文件讀入流對象
FileOutputStream fos =new FileOutputStream(file);
//3.定義結束標志
fos.write(要寫出的位元組或者位元組數組);
//4.刷新和關閉流
fos.flush();
fos.close();
//5.處理異常
三、緩沖流:
位元組緩沖流: BufferedInputStream,BufferedOutputStream
字元緩沖流:BufferedReader ,BufferedWriter
緩沖流是對流的操作的功能的加強,提高了數據的讀寫效率。既然緩沖流是對流的功能和讀寫效率的加強和提高,所以在創建緩沖流的對象時應該要傳入要加強的流對象。
//1.指定要讀 的文件目錄及名稱
File file =new File("文件路徑");
//2.創建文件讀入流對象
FileInputStream fis =new FileInputStream(file);
//3.創建緩沖流對象加強fis功能
BufferedInputStream bis =new BufferedInputStream(fis);
//4.定義結束標志,可用位元組數組讀取
int i =0 ;
while((i = bis.read())!=-1){
//i 就是從文件中讀取的位元組,讀完後返回-1
}
//5.關閉流
bis.close();
//6.處理異常
//1.指定要寫到的文件目錄及名稱
File file =new File("文件路徑");
//2.創建文件讀入流對象
FileOutputStream fos =new FileOutputStream(file);
//3.創建緩沖流對象加強fos功能
BufferedOutputStream bos=new BufferedOutputStream(fos);
//4.向流中寫入數據
bos.write(要寫出的位元組或者位元組數組);
//5.刷新和關閉流
bos.flush();
bos.close();
//6.處理異常
四、對象流
ObjectInputStream ,ObjectOutputStream
不同於以上兩種類型的流這里只能用位元組對對象進行操作原因可以看上篇的編碼表比照原理
ObjectOutputStream對象的序列化:
將java程序中的對象寫到本地磁碟里用ObjectOutputStream
eg:將Person類的對象序列化到磁碟
創建Person類
注1:此類要實現Serializable介面,此介面為標志性介面
注2:此類要有無參的構造函數
注3:一旦序列化此類不能再修改
class Person implements Serializable{
public Person(){}
}
2.創建對象流對象
註:要增強功能可以將傳入文件緩沖流
ObjectOutputStream oos =new ObjectOutputStream(
new FileOutputStream(new File("文件路徑")));
3.寫入對象 ,一般會將對象用集合存儲起來然後直接將集合寫入文件
List<Person> list =new ArrayList<>();
list.add(new Person());
...(可以添加多個)
oos.writeObject(list);
4.關閉流,處理異常
oos.flush();
oos.close();
五、轉換流:
這類流是用於將字元轉換為位元組輸入輸出,用於操作字元文件,屬於字元流的子類,所以後綴為reader,writer;前綴inputstream,outputstream;
注 :要傳入位元組流作為參賽
InputStreamReader: 字元轉換輸出流
OutputStreamWriter:字元轉換輸入流
//1.獲取鍵盤輸入的位元組流對象
inInputStream in =Stream.in;
/*2.用轉換流將位元組流對象轉換為字元流對象,方便調用字元緩沖流的readeLine()方法*/
InputStreamReader isr =new InputStreamReader(in);
/*5.創建字元轉換輸出流對象osw,方便把輸入的字元流轉換為位元組輸出到本地文件。*/
OutputStreamWriter osw =new OutputStreamWriter(new
FileOutputStream(new File("文件名")));
/*3.現在isr是字元流,可以作為參數傳入字元緩沖流中*/
BufferedReader br =new BufferedReader(isr);
/*4.可以調用字元緩沖流br的readLine()方法度一行輸入文本*/
String line =null;
while((line =br.readLine()){
osw.write(line);//osw是字元流對象,可以直接操作字元串
}
註:InputStreamReader isr =new InputStreamReader(new "各種類型的位元組輸入流都行即是:後綴為InputStream就行");
OutputStreamWriter osw =new OutputStreamWriter(new
"後綴為OutputStream就行");
六、區別記憶
1.對象流是可以讀寫幾乎所有類型的只要是對象就行,而位元組字元流,只能讀寫單個位元組字元或者位元組字元數組,以上沒有讀寫位元組字元數組的;注意對象流只有位元組流!
2.字元和位元組循環讀入的結束條件int i=0; (i =fis.read())!=-1
用字元數組復制文件(fr 讀入流 ,fw寫出流),位元組流也是相同的用法
int i = 0; char[] c = new char[1024];
while((i = fr.reade()) !=-1)){
fw.write(c,0,i);
}
123456
3.對象流裡面套緩沖流的情景:
new ObjectInputStream(new BufferedInputStream(new FileInputStream(new File(「文件路徑」))));
4.記憶流及其功能的方法:
前綴表示功能,後綴表示流的類型;
比如說FileInputStream 前綴:File,表示操作的磁碟,後綴:intputstream,表示是位元組輸入流。
同理 FileReader:表示操作文件的字元流
ObjectInputStream :操作對象的位元組輸入流
5.拓展:獲取鍵盤輸入的字元的緩沖流的寫法:
new BufferedReader(new InputStreamReader(System.in)));
將位元組以字元形式輸出到控制台的字元緩沖流的寫法:
new BufferedWriter( new OutputStreamWriter(System.out))
Ⅳ java中的流是什麼
流是個抽象的概念,是對輸入輸出設備的抽象,Java程序中,對於數據的輸入/輸出操作都是以「流」的方式進行。設備可以是文件,網路,內存等。
流具有方向性,至於是輸入流還是輸出流則是一個相對的概念,一般以程序為參考,如果數據的流向是程序至設備,我們成為輸出流,反之我們稱為輸入流。
可以將流想像成一個「水流管道」,水流就在這管道中形成了,自然就出現了方向的概念。
當程序需要從某個數據源讀入數據的時候,就會開啟一個輸入流,數據源可以是文件、內存或網路等等。相反地,需要寫出數據到某個數據源目的地的時候,也會開啟一個輸出流,這個數據源目的地也可以是文件、內存或網路等等。
可以從不同的角度對流進行分類:
1. 處理的數據單位不同,可分為:字元流,位元組流
2.數據流方向不同,可分為:輸入流,輸出流
3.功能不同,可分為:節點流,處理流
1. 和 2. 都比較好理解,對於根據功能分類的,可以這么理解:
節點流:節點流從一個特定的數據源讀寫數據。即節點流是直接操作文件,網路等的流,例如FileInputStream和FileOutputStream,他們直接從文件中讀取或往文件中寫入位元組流。
處理流:「連接」在已存在的流(節點流或處理流)之上通過對數據的處理為程序提供更為強大的讀寫功能。過濾流是
使用一個已經存在的輸入流或輸出流連接創建的,過濾流就是對節點流進行一系列的包裝。例如BufferedInputStream和
BufferedOutputStream,使用已經存在的節點流來構造,提供帶緩沖的讀寫,提高了讀寫的效率,以及DataInputStream和
DataOutputStream,使用已經存在的節點流來構造,提供了讀寫Java中的基本數據類型的功能。他們都屬於過濾流。
來源:
http://www.cnblogs.com/shitouer/archive/2012/12/19/2823641.html
Ⅳ java 中簡述使用流進行讀寫文本文件的步驟
InputStream
三個基本的讀方法
abstract int read() : 讀取一個位元組數據,並返回讀到的數據,如果返回-1,表示讀到了輸入流的末尾。
int read(byte[] b) : 將數據讀入一個位元組數組,同時返回實際讀取的位元組數。如果返回-1,表示讀到了輸入流的末尾。
int read(byte[] b, int off, int len) :將數據讀入一個位元組數組,同時返回實際讀取的位元組數。如果返回-1,表示讀到了輸入流的末尾。off指定在數組b中存放數據的起始偏移位置;len指定讀取的最大位元組數。
OutputStream
三個基本的寫方法
abstract void write(int b) :往輸出流中寫入一個位元組。
void write(byte[] b) :往輸出流中寫入數組b中的所有位元組。
void write(byte[] b, int off, int len) :往輸出流中寫入數組b中從偏移量off開始的len個位元組的數據。
其它方法
void flush() :刷新輸出流,強制緩沖區中的輸出位元組被寫出。
void close() :關閉輸出流,釋放和這個流相關的系統資源。
Ⅵ Java字元流和位元組流對文件操作的區別
Java字元流是處理字元(Char)對象用的,位元組流是處理位元組(Byte)對象用的。處理的目標對象不同,處理方法也就不一樣了。
字元流處理的基本單位是字元(Java中的字元是16位的),輸入流以Reader為基礎,輸出流以Writer為基礎;
位元組流的基本單位是位元組(Java中的位元組是8位的),輸入流以 InputStream為基礎,輸出流以 OutputStream為基礎;
字元流在輸入時可以按字元讀取,也可以按行讀取,會去掉回車換行,常用於讀取字元數據;
而位元組流按位元組讀取,不作任何處理,常用於讀取二進制數據。
Java中的字元在內部都是使用Unicode進行表示的,因此,要正確讀取字元數據,需要知道字元的編碼字元集,字元流提供編碼字元集的指定,如果不指定使用系統默認的方式對字元數據進行編碼轉換,這個編碼字元集不正確,會造成讀進來的地字元出現亂碼。
位元組流雖然是讀取二進制數據用的,但也可以讀取字元文件,按位元組進行處理,讀進來之後可以根據編碼字元集進行轉換,也可以變成字元串。
Ⅶ Java中有幾種類型的流
位元組流類
抽象父類: InputStream,OutputStream
實現類包括如下幾種:
BufferedInputStream 緩沖流-過慮流
BufferedOutputStream
ByteArrayInputStream 位元組數組流-節點流
ByteArrayOutputStream
DataInputStream 處理JAVA標准數據流-過慮流
DataOutputStream
FileInputStream 處理文件IO流-節點流
FileOutputStream
FilterInputStream 實現過慮流-位元組過慮流父類
FilterOutputStream
PipedInputStream 管道流
PipedOutputStream
PrintStream 包含print() 和 println()
RandomAccessFile 支持隨機文件
字元流
抽象父類:Reader, Writer