1. 程式人生 > >java中IO流,輸入輸出流的概述

java中IO流,輸入輸出流的概述

fis 需要 read 使用 找文件 output bytes 明顯 一次

1:Java語言定義了許多類專門負責各種方式的輸入或者輸出,這些類都被放在java.io包中。其中,

所有輸入流類都是抽象類InputStream(字節輸入流),或者抽象類Reader(字符輸入流)的子類;

而所有輸出流都是抽象類OutputStream(字節輸出流)或者Writer(字符輸出流)的子類。

【首先需要明白的是:流是幹什麽的???(為了永久性的保存數據)

根據數據流向的不同分為輸入流和輸出流;

根據處理數據類型的不同分為字符流和字節流;

【然後需要明白的是輸入模式和輸出模式是誰流向誰:

InputStream(字節輸入流)和Reader(字符輸入流)通俗的理解都是讀(read)的。

OutputStream(字節輸出流)和Writer(字符輸出流)通俗的理解都是寫(writer)的。

最後下面搞清楚各種流的類型的該怎麽用,誰包含誰,理清思路。

2:InputStream類是字節輸入流的抽象類,是所有字節輸入流的父類,InputStream類具有層次結構如下圖所示;

技術分享圖片

3:java中的字符是Unicode編碼的,是雙字節的。InputStream是用來處理字節的,在處理字符文本時很不方便。Java為字符文本的輸入提供了專門的一套類Reader。Reader類是字符輸入流的抽象類,所有字符輸入流的實現都是它的子類。

技術分享圖片

4:輸出流OutputStream類是字節輸出流的抽象類,此抽象類表示輸出字節流的所有類的超類。

技術分享圖片

5:Writer類是字符輸出流的抽象類,所有字符輸出類的實現都是它的子類。

技術分享圖片

6:下面以一些字節輸入輸出流具體的案例操作(操作的時候認清自己使用的是字節流還是字符流):

註意:read()方法讀取的是一個字節,為什麽返回是int,而不是byte。 字節輸入流可以操作任意類型的文件,比如圖片音頻等,這些文件底層都是以二進制形式的存儲的,如果每次讀取都返回byte,有可能在讀到中間的時候遇到111111111;那麽這11111111是byte類型的-1,我們的程序是遇到-1就會停止不讀了,後面的數據就讀不到了,所以在讀取的時候用int類型接收,如果11111111會在其前面補上;24個0湊足4個字節,那麽byte類型的-1就變成int類型的255了這樣可以保證整個數據讀完,而結束標記的-1就是int類型

FileInputStream的單個字節讀取:

FileOutputStream的單個字節寫入:

import java.io.FileInputStream;
import java.io.FileOutputStream;

//輸出流
public class fos_demo {
    public static void main(String[] args) throws Exception {
        FileInputStream fis = new FileInputStream("a.txt");
        FileOutputStream fos = new FileOutputStream("b.txt", true);
        //FileOutputStream()後面加true指文件後面可追加

        int a = fis.read();//單個讀取輸入流字節
        System.out.println(a);
        int b = fis.read();
        System.out.println(b);
        int c = fis.read();
        System.out.println(c);
        fos.write(97);//單個讀出字節
        fos.write(98);
        fos.write(99);
        fis.close();//關閉輸出流
        fos.close();//關閉輸出流
    }
}

FileInputStream和FileOutputStream進行拷貝文本或者圖片或者歌曲(以圖片為例):

方法一:
package IO; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; //拷貝圖片 public class copy_demo { public static void main(String[] args) throws IOException { copy(); } public static void copy() throws IOException { FileInputStream fis = new FileInputStream("aaa.jpg"); FileOutputStream fos = new FileOutputStream("copy.jpg"); byte[] bytes = new byte[fis.available()];//將圖片轉為字節數組,這樣會浪費空間 fis.read(bytes); fos.write(bytes); fis.close(); fos.close(); } }

方法二:
package IO;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class copy_demo1 {
    public static void main(String[] args) throws IOException{
        copy_2();
    }
    public static void copy_2() throws IOException{
        FileInputStream fis= new FileInputStream("aaa.jpg");
        FileOutputStream fos = new FileOutputStream("copy1.jpg");
        int b;
        while((b=fis.read())!=-1){
           fos.write(b);
        }
        fis.close();
        fos.close();
    }
}

FileInputStream和FileOutputStream定義小數組進行操作:

//拷貝圖片
package IO;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Array_copy {
    public static void main(String[] args) throws IOException {
        FileInputStream fis= new FileInputStream("aaa.jpg");
        FileOutputStream fos= new FileOutputStream("copy3.jpg");
        byte[] bytes = new byte[1024 * 8];//自定義字節大小
        int len;
        while ((len=fis.read(bytes))!=-1){
            fos.write(bytes,0,len);
        }
        fis.close();
        fos.close();
    }
}


//進行讀寫操作
package IO;

import java.io.FileInputStream;
import java.io.IOException;

public class Array_copy1 {
    public static void main(String[] args) throws IOException {
        test();
    }
    public static void test() throws IOException{
        FileInputStream fis = new FileInputStream("b.txt");
        byte[] bytes = new byte[3];//自定義讀取字節的個數
        int len=fis.read(bytes);
        System.out.println(len);
        for(byte a:bytes){
            System.out.println(a);
        }
        System.out.println("************");
        int len1=fis.read(bytes);//沒讀完的接著讀,依然是每次以上面自定義的讀取的個數讀
        System.out.println(len1);
        for(byte b:bytes){
            System.out.println(b);
        }
        fis.close();
    }
}

IO流(BufferedInputStream和BufferOutputStream拷貝)

* A:緩沖思想   * 字節流一次讀寫一個數組的速度明顯比一次讀寫一個字節的速度快很多,這是加入了數組這樣的緩沖區效果,java本身在設計的時候,也考慮到了這樣的設計思想,所以提 供了字節緩沖區流。 * B.BufferedInputStream   * BufferedInputStream內置了一個緩沖區(數組), 從BufferedInputStream中讀取一個字節時, BufferedInputStream會一次性從文件中讀取8192個, 存在緩沖區中, 返回 給程序,程序再次讀取時, 就不用找文件了, 直接從緩沖區中獲取,直到緩沖區中所有的都被使用過, 才重新從文件中讀取8192個。 * C.BufferedOutputStream   * BufferedOutputStream也內置了一個緩沖區(數組),程序向流中寫出字節時, 不會直接寫到文件, 先寫到緩沖區中,直到緩沖區寫滿, BufferedOutputStream才會把緩沖區 中的數據一次性寫到文件裏。
package IO;

import java.io.*;

//Buffer 相當於緩沖池 輸入輸出的轉化
public class Buffer_demo {
    public static void main(String[] args) throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("ren.jpg"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.jpg"));
        int len;
        while((len=bis.read())!=-1){
            bos.write(len);
        }
        bis.close();
        bos.close();
    }
}

 註意:

IO流(字符流是否可以拷貝非純文本的文件)

* 不可以拷貝非純文本的文件 * 因為在讀的時候會將字節轉換為字符,在轉換過程中,可能找不到對應的字符,就會用?代替,寫出的時候會將字符轉換成字節寫出去 * 如果是?,直接寫出,這樣寫出之後的文件就亂了,看不了了

 

 



java中IO流,輸入輸出流的概述