1. 程式人生 > >63. (FileInputStream)輸入字節流

63. (FileInputStream)輸入字節流

stream 系統資源 字符型 字符流 void 數組 字符變量 tst file

IO分類:
按照數據流向分類:
輸入流

輸出流

按照處理的單位劃分:
字節流:字節流讀取的都是文件中的二進制數據,讀取到的二進制數據不會經過任何處理

字符流:字符流讀取的數據都是以字符為單位的,字符流也是讀取的文件的二進制數據,只不過會把這些二進制數據轉換成我們能識別的字符
字符流 = 字節流 + 解碼

輸入字節流:
------------------|InputStream 所有輸入字節流的基類 抽象類
-----------|FileInputStream 讀取文件數據的輸入字節流 throws FileNotFoundException

FileInputStream中的一些方法:

構造方法:
FileInputStream(File file) 通過打開一個到實際文件的連接來創建一個 FileInputStream,該文件通過文件系統中的 File 對象 file 指定。

其中的一些方法:
read() 從此輸入流中讀取一個數據字節,如果已到達文件末尾,則返回 -1。throws IOException


read(byte[] b) throws IOException
把讀取的數據存儲到字節數組中,並返回本次讀取到字節數組中去的字節大小,如果一個也沒有返回-1
註意:
1.這裏的每次讀取到字符數組中是采用覆蓋的方式,也就是第一次如果讀取到字符數組中的數據是aaa第二次只讀取了bb,那麽現在數組中的數據是bba。
2.read(byte b[])方法實際上是調用了 read(byte b[], int off, int len)方法


read(byte[] b, int off, int len) 從此輸入流中將最多 len 個字節的數據讀入一個 byte 數組中。

close() 關閉此文件輸入流並釋放與此流有關的所有系統資源 throws IOException

註意:
當我們在創建通道的時候,也就是實例化FileInputStream的時候,裏面的指針會指向0,當我們每讀取一個數據字節指針都會加一

讀取文件的步驟:

1.找到目標文件
2.建立數據通道
3.讀取文件
4.關閉通道(釋放資源)

建議把實例看了後再看這個(百度的):

java中字符a和數字97的關系:

將一個字符常量放到一個字符變量中,實際是將該字符的相應的ASCII代碼放到存儲單元中。
如‘a’的ASCII代碼為十進制數97,c1=‘a‘,在內存中是以97的二進制01100001存儲的。
字符數據以ASCII碼存儲,它的存儲形式就與整數的存儲形式類似。這樣使字符型數據和整型數據之間可以通用。
字符數據只占一個字節,它只能存放0~255範圍內的整數。 註意:java中的char範圍是0-65535 這個可能隨著電腦不同和操作系統不同而不同

為什麽無參的read()方法的返回值是int類型而不是byte?

Java中的數字都是有符號數,假如我們用一個byte類型去接收流中的字節碼的話,
那麽假如剛好字節流裏的字節碼是-1的反碼,那這個時候,read()返回了一個-1,
那我們怎麽知道read()是到達了流的末端還是字節碼就是-1呢。
而假如我們使用int類型的c來接收這些字節碼,就不會出現這樣的問題,高位補零,
接收到的字節碼放在最低的八位上,這樣就能保證這些字節碼都是“正數”

下面是分別用read()方法和read(byte[] b)讀取數據

註意:在效率上面來說使用緩沖數組也就是用read(byte[] b)讀取數據效率要高很多

public class Demo1 {
    public static void main(String[] args){
        
        readFile1();
        System.out.println("\n---------");
        readFile2();
    }
    
    //read(byte[] b)  把讀取的數據存儲到字節數組中,並返回本次讀取到字節數組中去的字節大小,如果一個也沒有返回-1
public static void readFile1(){ FileInputStream fileInputStream = null; try { //找到目標文件 File file = new File("D:\\新建文件夾 (2)\\a.txt"); //建立數據通道 fileInputStream = new FileInputStream(file); //讀取文件(因為一次只能都取一個數據字節所以我們要用循環讀出所有內容) int content = 0; //條件:如果已到達文件末尾,read()會返回 -1 while((content = fileInputStream.read())!=-1) { //我們讀取的是一個ASCII碼,所以我們要把它強轉成我們能看得懂的字符 System.out.print((char)content); } }catch(IOException e){ //這裏用了一個運行時異常包裝我們IO異常(編譯時異常)發送出去,這樣就不會強制讓調用者處理異常,使調用者更加靈活 throw new RuntimeException(e); }finally { //關閉通道(釋放資源) //為了確保上面出現異常後,資源不能被釋放的情況,我們一般會把關閉資源寫在finally塊裏面 try{ fileInputStream.close(); }catch(IOException e){ //這裏也用了一個運行時異常包裝我們IO異常(編譯時異常)發送出去 throw new RuntimeException(e); } } } //使用read(byte[] b)讀取數據 :從此輸入流中將最多 b.length 個字節的數據讀入一個 byte數組中。如果沒有那麽返回-1 //註意:這裏的每次讀取到字符數組中是采用覆蓋的方式,也就是第一次如果讀取到字符數組中的數據是aaa //第二次只讀取了bb,那麽現在數組中的數據是bba。 public static void readFile2(){ FileInputStream fileInputStream = null; try { //找到目標文件 File file = new File("D:\\新建文件夾 (2)\\a.txt"); //建立數據通道 fileInputStream = new FileInputStream(file); //定義變量,存儲本次讀取的字節大小 int length = 0; //讀取文件(創建緩存數組,把讀取到的數據存儲到數組中) //一般字符數組的大小是2048的倍數,這個跟計算機的處理單位有關,“理論”上來說字節數組越大效率越高 byte[] buf = new byte[2048]; //條件:如果已到達文件末尾,read()會返回 -1 while((length = fileInputStream.read(buf))!=-1) { //把字符數組轉換成字符串並輸出 System.out.println(new String(buf,0,length)); //本次讀取到字符數組的字節大小為 System.out.println("本次讀取的數據的字節大小:"+length); } }catch(IOException e){ //這裏用了一個運行時異常包裝我們IO異常(編譯時異常)發送出去,這樣就不會強制讓調用者處理異常,使調用者更加靈活 throw new RuntimeException(e); }finally { //關閉通道(釋放資源) //為了確保上面出現異常後,資源不能被釋放的情況,我們一般會把關閉資源寫在finally塊裏面 try{ fileInputStream.close(); }catch(IOException e){ //這裏也用了一個運行時異常包裝我們IO異常(編譯時異常)發送出去 throw new RuntimeException(e); } } } }

技術分享圖片

63. (FileInputStream)輸入字節流