java IO流操做

什麼是IO流?

Java中I/O操做主要是指使用java.io包下的內容,進行輸入、輸出操做。輸入也叫作讀取數據,輸出也叫作做寫出數據。java

輸入輸出(IO): 輸入輸出是指計算機同任何外部設備之間的數據傳遞。數組

在IO流裏,輸入輸出分爲4步:格式化/解析,緩衝,編碼轉換和傳遞。緩存

格式化/解析:在內部數據表示(以字節爲單位)與外部數據表示(以字符爲單位)之間進行雙向轉換。例如一個2字節的整數10002,就須要5個字符來表示。編碼

緩衝:用於在格式/解析與傳遞之間緩存字符序列。對於輸出,較短的字符序列格式化以後並不立刻輸出,而是保存在緩衝區裏,待累積到必定規模以後再傳遞到外部設備。相反,從外部設備讀入的大量數據也是先放在緩衝區,而後逐步取出完成輸入。默認時,IO流的輸入輸出都是通過緩衝的,也可讓IO流工做在無緩衝模式下。線程

編碼轉換:是將一種字符表達式轉換成另外一種字符表達式。若是格式化產生的字符表達式與外部字符表達式不一樣(輸出時),或者外部表達式與IO流能解析的表達式不一樣(輸入時),就必須進行編碼轉換。如多字節編碼與寬字符編碼之間的轉換等。多數狀況下並不須要進行編碼轉換。code

傳遞:主要是與外部設備進行通訊。輸出時,傳遞負責將通過格式化、緩衝即編碼轉換後的字符序列發送到外部設備;輸入時,則負責將外部設備抽取數據,爲其後進行的編碼轉換、緩衝及解析提供字符序列。對象

IO流的分類:

根據數據的流向分爲:圖片

  • 輸入流 :把數據從其餘設備上讀取到內存中的流,只能進行讀操做。
  • 輸出流 :把數據從內存 中寫出到其餘設備上的流,只能進行寫操做。

根據數據的類型分爲:ip

  • 字節流 :以字節爲單位,讀寫數據的流。
  • 字符流 :以字符爲單位,讀寫數據的流。

字節流和字符流的區別:內存

  • 讀寫單位不一樣:字節流以字節爲單位,字符流以字符爲單位
  • 處理對象不一樣:字節流能處理全部類型的數據(如圖片、avi等),而字符流只能處理字符類型的數據。
  • 字節流:一次讀入或讀出是8位二進制。
  • 字符流:一次讀入或讀出是16位二進制。

分類以後對應的超類(超類也就是父類的意思) | | 輸入流 | 輸出流 |--|--|--| | 字節流 | 字節輸入流 InputStream |字節輸出流 OutputStream | | 字符流 | 字符輸入流 Reader|字符輸出流 Writer|

注: 由這四個類的子類名稱基本都是以其父類名做爲子類名的後綴。

字節輸入流 InputStream:

  • InputStream 是全部的字節輸入流 的父類,它是一個抽象類。
  • ByteArrayInputStreamStringBufferInputStreamFileInputStream 是三種基本的介質流,它們分別從Byte 數組StringBuffer、和本地文件中讀取數據。
  • PipedInputStream 是從與其它線程共用的管道中讀取數據。
  • ObjectInputStream 和全部FilterInputStream 的子類都是裝飾流(裝飾器模式的主角)。
FileInputStream fis = new FileInputStream("xxx.txt");//建立流對象    
int b;
while((b = fis.read()) != -1) { //字節輸入流對象fis一次讀一個字節 並賦值給b  判斷b是否是-1
    System.out.println(b);  
}
fis.close();

字節輸出流 OutputStream:

  • OutputStream 是全部的字節輸出流 的父類,它是一個抽象類。
  • ByteArrayOutputStreamFileOutputStream 是兩種基本的介質流,它們分別向Byte 數組、和本地文件中寫入數據。
  • PipedOutputStream 是向與其它線程共用的管道中寫入數據。
  • ObjectOutputStream 和全部FilterOutputStream 的子類都是裝飾流。
FileOutputStream fos = new FileOutputStream("yyy.txt"); 
fos.write(100);     //寫出的是一個int數,可是到文件上的是一個字節,會自動去除前三個8位
fos.write(99);      //此時文件yyy.txt中是 dc
fos.close();

注意:

1)輸出流輸出數據在建立輸出流對象的時候,若是不存在文件,就建立一個;若是存在就清空該文件數據,而後寫入數據。 2)若是想在文件裏面追加寫入就用new FileOutputStream(String pathName,true)這個構造方法。

字符輸入流:

public int read():讀取單個字符,並返回成int,若是已到達流的末尾,則返回 -1 public int read(char[] cbuf):將字符讀入數組,返回讀取的字符數,若是已到達流的末尾,則返回 -1

public static void main(String[] args) throws IOException {
    FileReader fr = new FileReader("xxx.txt");  //建立字符輸入流對象
    int c;
    
    while((c = fr.read()) != -1) {  //經過項目默認的碼錶一次讀取一個字符
        System.out.print((char)c);  //將c強制類型轉換成char
    }
    fr.close();
}

字符輸出流:

public void write(int c):寫入單個字符。 public void write(char[] cbuf):寫入字符數組。 public abstract void write(char[] cbuf,int off, int len):寫入字符數組的某一部分。cbuf - 字符數組,off - 開始寫入字符處的偏移量,len - 要寫入的字符數。 public void write(String str):寫入字符串。 public void write(String str,int off, int len):寫入字符串的某一部分。str - 字符串,off - 相對初始寫入字符的偏移量,len - 要寫入的字符數 。

節點流: 直接與數據源相連,讀入或讀出。

經常使用的節點流:

  • 父 類 :InputStreamOutputStreamReaderWriter
  • 文 件 :FileInputStreamFileOutputStreanFileReaderFileWriter 文件進行處理的節點流
  • 數 組 :ByteArrayInputStreamByteArrayOutputStreamCharArrayReaderCharArrayWriter 對數組進行處理的節點流(對應的再也不是文件,而是內存中的一個數組)
  • 字符串 :StringReaderStringWriter 對字符串進行處理的節點流
  • 管 道 :PipedInputStreamPipedOutputStreamPipedReaderPipedWriter 對管道進行處理的節點流

處理流: 處理流和節點流一塊使用,在節點流的基礎上,再套接一層,套接在節點流上的就是處理流。

經常使用的處理流:

  • 緩衝流:BufferedInputStreanBufferedOutputStreamBufferedReaderBufferedWriter 增長緩衝功能,避免頻繁讀寫硬盤。
  • 轉換流:InputStreamReaderOutputStreamReader實現字節流和字符流之間的轉換。
  • 數據流: DataInputStreamDataOutputStream 等-提供將基礎數據類型寫入到文件中,或者讀取出來。

轉換流: InputStreamReaderOutputStreamWriterInputStreamOutputStream做爲參數,實現從字節流到字符流的轉換。

序列流: 序列流能夠把多個字節輸入流整合成一個, 從序列流中讀取數據時, 將從被整合的第一個流開始讀, 讀完一個以後繼續讀第二個, 以此類推。

1)整合兩個輸入流SequenceInputStream(InputStream s1, InputStream s2);

public static void demo2() throws FileNotFoundException, IOException {
    FileInputStream fis1 = new FileInputStream("a.mp3");
    FileInputStream fis2 = new FileInputStream("b.mp3");
    SequenceInputStream sis = new SequenceInputStream(fis1, fis2);
    FileOutputStream fos = new FileOutputStream("c.mp3");
    //歌曲串燒,c.mp3裏面有a.mp3和b.mp3兩首歌

    int b;
    while((b = sis.read()) != -1) {
        fos.write(b);
    }

    sis.close();        //sis在關閉的時候,會將構造方法中傳入的流對象也都關閉
    fos.close();
}

2)整合多個輸入流 SequenceInputStream(Enumeration<? extends InputStream> e)

public static void main(String[] args) throws IOException {

    FileInputStream fis1 = new FileInputStream("a.txt");
    FileInputStream fis2 = new FileInputStream("b.txt");
    FileInputStream fis3 = new FileInputStream("c.txt");

    Vector<FileInputStream> v = new Vector<>();     //建立集合對象
    v.add(fis1);                        //將流對象存儲進來
    v.add(fis2);
    v.add(fis3);

    Enumeration<FileInputStream> en = v.elements();
    SequenceInputStream sis = new SequenceInputStream(en);  //將枚舉中的輸入流整合成一個
    FileOutputStream fos = new FileOutputStream("d.txt");

    int b;
    while((b = sis.read()) != -1) {
        fos.write(b);
    }

    sis.close();
    fos.close();
}
相關文章
相關標籤/搜索