91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java的FileInputStream流如何使用

發布時間:2021-12-12 17:56:02 來源:億速云 閱讀:147 作者:iii 欄目:開發技術

這篇文章主要介紹“java的FileInputStream流如何使用”,在日常操作中,相信很多人在java的FileInputStream流如何使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”java的FileInputStream流如何使用”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

    一、File流概念

    JAVA中針對文件的讀寫操作設置了一系列的流,其中主要有FileInputStream,FileOutputStream,FileReader,FileWriter四種最為常用的流

    二、FileInputStream

    1)FileInputStream概念

    FileInputStream流被稱為文件字節輸入流,意思指對文件數據以字節的形式進行讀取操作如讀取圖片視頻等

    2)構造方法

    2.1)通過打開與File類對象代表的實際文件的鏈接來創建FileInputStream流對象

    public FileInputStream(File file) throws FileNotFoundException{}

    若File類對象的所代表的文件不存在;不是文件是目錄;或者其他原因不能打開的話,則會拋出FileNotFoundException

    /**
         * 
         * 運行會產生異常并被撲捉--因為不存在xxxxxxxx這樣的文件
         */
    public static void main(String[] args)
        {
            File file=new File("xxxxxxxx"); //根據路徑創建File類對象--這里路徑即使錯誤也不會報錯,因為只是產生File對象,還并未與計算機文件讀寫有關聯
            
            try
            {
                FileInputStream fileInputStream=new FileInputStream(file);//與根據File類對象的所代表的實際文件建立鏈接創建fileInputStream對象
            }
            catch (FileNotFoundException e)
            {
              
               System.out.println("文件不存在或者文件不可讀或者文件是目錄");
            } 
        }

    2.2)通過指定的字符串參數來創建File類對象,而后再與File對象所代表的實際路徑建立鏈接創建FileInputStream流對象

    public FileInputStream(String name) throws FileNotFoundException

    通過查看源碼,發現該構造方法等于是在第一個構造方法的基礎上進行延伸的,因此規則也和第一個構造方法一致

    public FileInputStream(String name) throws FileNotFoundException {
            this(name != null ? new File(name) : null);
        }

    2.3)該構造方法沒有理解---查看api是指使用的fdObj文件描述符來作為參數,文件描述符是指與計算機系統中的文件的連接,前面兩個方法的源碼中最后都是利用文件描述符來建立連接的

    public FileInputStream(FileDescriptor fdObj)

    3)FileInputStream常用API

    3.1)從輸入流中讀取一個字節返回int型變量,若到達文件末尾,則返回-1

    public int read() throws IOException

    理解讀取的字節為什么返回int型變量

    1、方法解釋中的-1相當于是數據字典告訴調用者文件已到底,可以結束讀取了,這里的-1是Int型

    2、那么當文件未到底時,我們讀取的是字節,若返回byte類型,那么勢必造成同一方法返回類型不同的情況這是不允許的

    3、我們讀取的字節實際是由8位二進制組成,二進制文件不利于直觀查看,可以轉成常用的十進制進行展示,因此需要把讀取的字節從二進制轉成十進制整數,故返回int型

    4、 因此結合以上3點,保證返回類型一致以及直觀查看的情況,因此該方法雖然讀取的是字節但返回int型

    read方法讀取實例--最后輸出內容和字符內容一致是123

    package com.test; 
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException; 
    public class FileStream
    {
        /**
         * 
         *
         */
        public static void main(String[] args)
        {
            //建立文件對象
            File file=new File("C:\\Users\\Administrator\\Desktop\\1.txt");    
            try
            {
                //建立鏈接
                FileInputStream fileInputStream=new FileInputStream(file);            
                int  n=0;             
                StringBuffer sBuffer=new StringBuffer(); 
                while (n!=-1)  //當n不等于-1,則代表未到末尾
                {                
                   n=fileInputStream.read();//讀取文件的一個字節(8個二進制位),并將其由二進制轉成十進制的整數返回              
                   char by=(char) n; //轉成字符               
                   sBuffer.append(by); 
                }
               System.out.println(sBuffer.toString());   
            }
            catch (FileNotFoundException e)
            {          
               System.out.println("文件不存在或者文件不可讀或者文件是目錄");
            }
            catch (IOException e)
            {
               System.out.println("讀取過程存在異常");
            } 
        } 
    }

    3.2)從輸入流中讀取b.length個字節到字節數組中,返回讀入緩沖區的總字節數,若到達文件末尾,則返回-1

    public int read(byte[] b) throws IOException

    1. 我們先設定一個緩沖區即字節數組用于存儲從流中讀取的字節數據,該數組的長度為N

    2. 那么就是從流中讀取N個字節到字節數組中。但是注意返回的是讀入的總字節數而并不是N,說明有的時候實際讀入的總字節數不一定等于數組的長度

    3. 文件的內容是12345.那么流中一共有5個字節,但是我們設定的字節數組長度為2.那么會讀取幾次?每次情況是怎么樣的?

    public class FileStream
    { 
        public static void main(String[] args)
        {
            //建立文件對象
            File file=new File("C:\\Users\\Administrator\\Desktop\\1.txt");    
            try
            {
                //建立鏈接
                FileInputStream fileInputStream=new FileInputStream(file);
                
                int  n=0;             
                byte[] b=new byte[2];            
                int i=0; 
                while (n!=-1)  //當n不等于-1,則代表未到末尾
                {                
                   n=fileInputStream.read(b);//返回實際讀取到字節數組中的字節數               
                   System.out.println(n);                
                   System.out.println(Arrays.toString(b)); //讀取后的字節數組內容               
                   i++;               
                   System.out.println("執行次數:"+i); 
                } 
                System.out.println(new String(b));   
            }
            catch (FileNotFoundException e)
            {          
               System.out.println("文件不存在或者文件不可讀或者文件是目錄");
            }
            catch (IOException e)
            {
               System.out.println("讀取過程存在異常");
            } 
        } 
    }

    實際執行結果如下:

    java的FileInputStream流如何使用

    可以看出,數組長度為2,因此第一次讀取2個字節到數組中,數組已經被填滿。流中還剩余3個字節繼續讀取

    第二次讀取,仍然讀取2個字節到數組中,數組內容被替換。此時流中只剩余1個字節,根據API說明,讀取數組長度(2)個字節到數組中,但接下來已經無法繼續讀取2個字節了, 是否就應該停止了?

    實際過程中并未停止,而是進行了第三次讀取,只讀取了剩余1個字節,并頂替到了數組的0下標位置中。

    接下來第4次讀取,才發現移到末尾,而后返回-1.停止讀取

    所以此處存疑-----為什么當剩余只有1個字節,而要求是讀取2個字節時,還可以繼續讀取?

    那么我們查看此方法源碼,發現其本質是調用的其它方法readBytes(b, 0, b.length);

    public int read(byte b[]) throws IOException {
            return readBytes(b, 0, b.length);
        }

    繼續查看readBytes(b, 0, b.length)方法是native方法代表該方法是有實現體的但不是在JAVA語言中實現的導致沒辦法看具體實現

    但是可以理解參數b是我們設置的數組,0是int型,最后一個參數是數組的長度

     private native int readBytes(byte b[], int off, int len) throws IOException;

    那么我們查看FileInputStream的父類InputStream,發現有關于這個方法的實現,

    我們現在考慮第三次讀取的時候方法執行情況,此時b是[51,52].off 是0,len是2。數據流中就只有一個字節存在了

    if else if的這個條件判斷發現都不符合,繼續往下執行。

    read()--該方法代表從流中讀取一個字節,而流中此時剛好還有一個字節存在,該方法執行沒有問題。返回值為53

    繼續往下執行發現b[0]=(byte)53.也就是將讀取到的int型轉為字節并存儲在數組中的第一個位置,此時數組內容為[53,52]

    繼續執行進入for循環,此時流中已沒有字節,那么read()方法返回未-1退出循環。返回變量i的值即是1.

    也就是此次方法執行讀取了1個字節到數組中。且讀取到了文件的末尾,因此第4次執行的時候到int c=read()方法時就已經返回-1,并沒有替換數組中的值了

      public int read(byte b[], int off, int len) throws IOException {
            if (b == null) {
                throw new NullPointerException();
            } else if (off < 0 || len < 0 || len > b.length - off) {
                throw new IndexOutOfBoundsException();
            } else if (len == 0) {
                return 0;
            }
     
            int c = read();
            if (c == -1) {
                return -1;
            }
            b[off] = (byte)c;
     
            int i = 1;
            try {
                for (; i < len ; i++) {
                    c = read();
                    if (c == -1) {
                        break;
                    }
                    b[off + i] = (byte)c;
                }
            } catch (IOException ee) {
            }
            return i;
        }

    讀取過程圖解:

    java的FileInputStream流如何使用

    4. 假設流中一共有5個字節,但是我們設定的字節數組長度為10,那么讀取幾次?每次情況是怎么樣的?

    public class FileStream
    { 
        public static void main(String[] args)
        {
            //建立文件對象
            File file=new File("C:\\Users\\Administrator\\Desktop\\1.txt");    
            try
            {
                //建立鏈接
                FileInputStream fileInputStream=new FileInputStream(file);            
                int  n=0;             
                byte[] b=new byte[10];            
                int i=0; 
                while (n!=-1)  //當n不等于-1,則代表未到末尾
                {                
                   n=fileInputStream.read(b);//返回實際讀取到字節數組中的字節數               
                   System.out.println(n);                
                   System.out.println(Arrays.toString(b)); //讀取后的字節數組內容               
                   i++;               
                   System.out.println("執行次數:"+i); 
                } 
                System.out.println(new String(b));   
            }
            catch (FileNotFoundException e)
            {          
               System.out.println("文件不存在或者文件不可讀或者文件是目錄");
            }
            catch (IOException e)
            {
               System.out.println("讀取過程存在異常");
            } 
        } 
    }

    執行結果如下:

    java的FileInputStream流如何使用

    結合上面提到的源碼我們可以發現,源碼中的for循環,盡管len是10(數組長度),但是當i=5時,流中的字節已經讀取完畢,指針移到文件的末尾,因此不會繼續執行for循環。并且返回5,剛好符合結果中第一次實際讀取5個字節到數組中。第二次讀取時指針已到末尾。因此int c = read()這里返回-1。就已經結束了方法,并沒有改變數組也沒有再次for循環

    但是這種情況存在一個問題:即數組中有5個位置被浪費了,并沒有任何數據在里面

    具體讀取圖解:

    java的FileInputStream流如何使用

    結合以上兩種情況,那么發現在使用read(byte b[])方法時的數組長度至關重要,若長度小于流的字節長度,那么最后得出的內容會出現丟失。若大于流的字節長度,那么最后數組的內存就浪費了,那么就需要根據文件的字節長度來設置數組的長度

    byte[] b=new byte[(int) file.length()];

    3.3)從輸入流中讀取最多len個字節到字節數組中(從數組的off位置開始存儲字節),當len為0時則返回0,如果len不為零,則該方法將阻塞,直到某些輸入可用為止--此處存疑

    public int read(byte[] b,int off,int len) throws IOException

    源碼如下

      public int read(byte b[], int off, int len) throws IOException {
            if (b == null) {
                throw new NullPointerException();
            } else if (off < 0 || len < 0 || len > b.length - off) {
                throw new IndexOutOfBoundsException();
            } else if (len == 0) {
                return 0;
            }
     
            int c = read();
            if (c == -1) {
                return -1;
            }
            b[off] = (byte)c;
     
            int i = 1;
            try {
                for (; i < len ; i++) {
                    c = read();
                    if (c == -1) {
                        break;
                    }
                    b[off + i] = (byte)c;
                }
            } catch (IOException ee) {
            }
            return i;
        }

    3.4)關閉此輸入流并釋放與該流關聯的所有系統資源---即釋放與實際文件的連接(查看源碼可發現有同步鎖鎖住資源,因此關閉流釋放鎖

    public void close() throws IOException

    三、三種read方法效率比較

    1、查看三種read方法源碼,其本質都是利用for循環對內容進行單字節的讀取

    2、從代碼形式看,使用read(byte[] b)較為直觀和簡便,因此項目中可以此方法為主進行數據讀取

    到此,關于“java的FileInputStream流如何使用”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    花垣县| 山阴县| 阳高县| 阆中市| 长宁县| 卓尼县| 达孜县| 米易县| 大姚县| 定南县| 和平区| 龙门县| 怀来县| 赤壁市| 中卫市| 湘潭县| 扎囊县| 松原市| 茌平县| 金阳县| 环江| 朔州市| 南陵县| 南召县| 孝昌县| 邓州市| 祁东县| 阜宁县| 汉沽区| 大同县| 廉江市| 襄垣县| 尼木县| 永春县| 天水市| 福泉市| 马鞍山市| 兴宁市| 汾阳市| 正阳县| 房产|