天天看點

了解java的I/O流:

了解java的I/O流:

Java的IO流是實作輸入輸出的基礎,他可以友善的實作資料的輸入輸出操作,在Java中把不同的輸入/輸出園(鍵盤,檔案,網絡連接配接等)抽象描述為流(stream),通過流的方式允許Java程式使用相同的方式來通路不同的輸入輸出源。

Java把所有傳統的流類型(類或抽象類)都放在java.io中包中,用以實作輸入輸出功能。

因為Java提供了這種IO流的抽象,是以開發者可以使用一緻的IO代碼去讀寫不同的IO流節點。

(1)流的分類:

1.輸入流和輸出流:

按照流的流向來分,可以分為輸入流和輸出流。

輸入流:隻能從中讀取資料,而不能向其寫入資料

輸出流:隻能向其寫入資料,而不能從中讀取資料。

Java的輸入流主要由InputStream和Reader作為基類,而輸出流主要由OutputStream和Writer作為基類,他們都是一些抽象基類,無法直接建立執行個體。

2.位元組流和字元流:位元組流和字元流的用法幾乎完全一樣,差別在于位元組流和字元流所操作的資料單元不同,位元組流操作的是8位的位元組,而字元流操作的是16位的字元。

位元組流主要由InputStream和OutputStream作為基類,而字元流主要由Reader和Writer作為基類。

3.節點流和處理流:

按照流的角色來分,可以分為節點流和處理流:

可以和一個特定的IO裝置讀寫資料的流,稱為節點流,節點流也被稱為低級流(Low Level Stream)

處理流則用于對一個已存在的流進行連接配接或封裝,通過封裝後的流來實作資料讀寫的功能。處理流也被稱為進階流。

當使用處理流進行輸入輸出時,程式并不會連接配接到實際的資料庫,沒有和實際的輸入輸出節點連接配接。使用處理流的一個明顯好處是,隻要使用相同的處理流,程式就可以采用完全相同的輸入輸出代碼來翻不過問不同的資料源,随着處理流所包裝節點流的變化,程式實際所有所通路的資料源也相應的發生變化。

實際上,Java使用處理流來包裝節點流是一種典型的裝飾器設計模式,通過使用處理流來包裝不同的節點流,既可以消除不同節點流的實作差異,也可以提供更友善的方法完成輸入輸出功能。是以處理流也被稱為包裝流。

——————————————————————————————————————————

位元組流和字元流:

InputStream和Reader:

InputStream和Reader是所有輸入流的抽象基類,本身并不能建立執行個體來執行輸入,但他們将成為所有輸入流的模闆,是以他們的方法是所有輸入流都可以使用的方法:

在InputStream裡包含如下三個方法:

int read() 從輸入流中讀取單個位元組,傳回所讀取的位元組資料(位元組資料可直接轉換為int類型)

int read(byte[] b) 從輸入流中最多讀取b.length個位元組的資料,并将其存儲在數組b中,傳回實際讀取的位元組數。

int read(byte [ ] b,int off, int len): 從輸出流中讀取len個位元組的資料,并将其存儲在資料b中,并不是從數組起點開始,而是從off位置開始,傳回實際讀取的位元組數。

在Reader裡包含如下三個方法:

int read() 從輸入流中讀取單個字元,傳回所讀取的位元組資料,字元資料可直接轉換為int類型)

int read(char[] cbuf) 從輸入流中最多讀取cbuf.length個字元的資料,并将其存儲在數組cbuf中,傳回實際讀取的字元數。

int read(char [ ] cbuf,int off, int len): 從輸出流中讀取len個字元的資料,并将其存儲在資料cbuf中,并不是從數組起點開始,而是從off位置開始,傳回實際讀取的cbuf

數。

(2)InputStream和Reader都是抽象類,本身不能建立執行個體,但他們分别有一個用于讀取檔案的輸入流:FileInputStrean和FileReader,他們都是節點流,會直接和指定檔案關聯。

//FileInputStream來讀取自身

OutputStream和Writer:提供的方法

void write(int c) 将指定的位元組字元流輸出到輸出流中,c可以代表位元組和字元

void write(byte[] /char[] buf) 把位元組字元數組中的資料輸出到指定輸出流中

void write(byte[] /char[] buf,int off,int len) 将位元組數組字元數組從off位置開始,長度為len的位元組字元流輸出到輸出流中

Writer還有如下兩個方法:

void write(String str) 将str字元串裡包含的字元輸出到指定輸出流中

void write(String str,int off ,int len)

//使用FileInputStream來執行輸入,并使用FileOutputStream來執行輸出,用于實作複制FileOutputStreamTest.java

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamTest{
     public static void main(String[] args) throws IOException {
           //建立數字輸入流
           FileInputStream  fis=new FileInputStream("FileOutputStreamTest.java");
           //建立位元組輸出流
           FileOutputStream  fos=new  FileOutputStream("newFile.txt");
           byte []  bbuf=new  byte[];
           int hasRead =;
           //循環從輸入流中取出資料
           while((hasRead=fis.read(bbuf))>){
                //每讀一次,即寫入檔案輸出流,讀了多少,就寫多少
                fos.write(bbuf,,hasRead);
           }
     }
}

           

處理流的用法:

(1)使用處理流的典型思路是,使用處理流來包裝節點流,程式通過處理流來執行輸入輸出功能,讓節點流與底層的IO裝置檔案互動。

(2)實際識别處理流非常簡單,隻要流的構造器參數不是一個實體節點,而是已經存在的流,那麼這種流一定是處理流,而所有的節點流都是直接以實體IO作為構造器參數的。

//使用PrintStream處理流來包裝OutputStream。
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
public class PrintStreamTest{
     public static void main(String[] args) throws FileNotFoundException {
           FileOutputStream  fos=new FileOutputStream("test.txt");
           PrintStream  ps=new  PrintStream(fos);
           //使用PrintStream執行輸出
           ps.println("普通字元串");
           //直接使用PrintStream輸出對象
           ps.println(new  PrintStreamTest());
     }
}
           

轉換流:

輸入輸出流體系中還提供了兩個轉換流,用于實作将位元組流轉換成字元流,其中InputStreamReader将位元組輸入流轉換成字元輸入流,OutputStreamWriter将位元組輸出流轉換為字元輸出流。

//以擷取鍵盤輸入為例來介紹轉換流的做法

Java使用System.in代表标準輸入,即鍵盤輸入,但這個标準輸入流是InputStream類的執行個體,使用不友善,而且鍵盤輸入内容都是文本内容,是以可以使用InputStreamReader将其轉換為字元輸入流,普通的Reader讀取内容時讀取輸入内容來說也不友善,可以将普通的Reader再次包裝成BufferedReader,利用BufferedReader的readLine()方法可以一次讀取一行内容:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public  class  keyinTest{
     public static void main(String[] args) throws IOException {
           //将System.in對象轉換為Reader對象
           InputStreamReader  reader=new  InputStreamReader(System.in);
           //将普通的Reader包裝為BufferReader
           BufferedReader  br=new BufferedReader(reader);
           String  line=null;
           //采用循環方式來逐行進行讀取
           while((line  =br.readLine())!=null){
                //如果程式讀取的字元串是exit,則退出
                if(line.equals("exit"));
                {
                     System.exit();
                }
                //列印讀取的内容
                System.out.println("輸入内容為:"+line);
           }
     }
}