最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java基礎知識之FileInputStream流的使用

 更新時間:2021年12月09日 17:09:21   作者:咕嚕是個大胖子  
這篇文章主要介紹了java基礎知識之FileInputStream流的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

一、File流概念

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

二、FileInputStream

1)FileInputStream概念

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

2)構造方法

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

public FileInputStream(File file) throws FileNotFoundException{}

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

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

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

public FileInputStream(String name) throws FileNotFoundException

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

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

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

public FileInputStream(FileDescriptor fdObj)

3)FileInputStream常用API

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

public int read() throws IOException

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

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

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

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

4、 因此結合以上3點,保證返回類型一致以及直觀查看的情況,因此該方法雖然讀取的是字節(jié)但返回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();//讀取文件的一個字節(jié)(8個二進制位),并將其由二進制轉成十進制的整數(shù)返回              
               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個字節(jié)到字節(jié)數(shù)組中,返回讀入緩沖區(qū)的總字節(jié)數(shù),若到達文件末尾,則返回-1

public int read(byte[] b) throws IOException

1. 我們先設定一個緩沖區(qū)即字節(jié)數(shù)組用于存儲從流中讀取的字節(jié)數(shù)據(jù),該數(shù)組的長度為N

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

3. 文件的內容是12345.那么流中一共有5個字節(jié),但是我們設定的字節(jié)數(shù)組長度為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);//返回實際讀取到字節(jié)數(shù)組中的字節(jié)數(shù)               
               System.out.println(n);                
               System.out.println(Arrays.toString(b)); //讀取后的字節(jié)數(shù)組內容               
               i++;               
               System.out.println("執(zhí)行次數(shù):"+i); 
            } 
            System.out.println(new String(b));   
        }
        catch (FileNotFoundException e)
        {          
           System.out.println("文件不存在或者文件不可讀或者文件是目錄");
        }
        catch (IOException e)
        {
           System.out.println("讀取過程存在異常");
        } 
    } 
}

實際執(zhí)行結果如下:

可以看出,數(shù)組長度為2,因此第一次讀取2個字節(jié)到數(shù)組中,數(shù)組已經(jīng)被填滿。流中還剩余3個字節(jié)繼續(xù)讀取

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

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

接下來第4次讀取,才發(fā)現(xiàn)移到末尾,而后返回-1.停止讀取

所以此處存疑-----為什么當剩余只有1個字節(jié),而要求是讀取2個字節(jié)時,還可以繼續(xù)讀?。?/p>

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

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

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

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

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

那么我們查看FileInputStream的父類InputStream,發(fā)現(xiàn)有關于這個方法的實現(xiàn),

我們現(xiàn)在考慮第三次讀取的時候方法執(zhí)行情況,此時b是[51,52].off 是0,len是2。數(shù)據(jù)流中就只有一個字節(jié)存在了

if else if的這個條件判斷發(fā)現(xiàn)都不符合,繼續(xù)往下執(zhí)行。

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

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

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

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

  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;
    }

讀取過程圖解:

4. 假設流中一共有5個字節(jié),但是我們設定的字節(jié)數(shù)組長度為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);//返回實際讀取到字節(jié)數(shù)組中的字節(jié)數(shù)               
               System.out.println(n);                
               System.out.println(Arrays.toString(b)); //讀取后的字節(jié)數(shù)組內容               
               i++;               
               System.out.println("執(zhí)行次數(shù):"+i); 
            } 
            System.out.println(new String(b));   
        }
        catch (FileNotFoundException e)
        {          
           System.out.println("文件不存在或者文件不可讀或者文件是目錄");
        }
        catch (IOException e)
        {
           System.out.println("讀取過程存在異常");
        } 
    } 
}

執(zhí)行結果如下:

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

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

具體讀取圖解:

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

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

3.3)從輸入流中讀取最多l(xiāng)en個字節(jié)到字節(jié)數(shù)組中(從數(shù)組的off位置開始存儲字節(jié)),當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)關閉此輸入流并釋放與該流關聯(lián)的所有系統(tǒng)資源---即釋放與實際文件的連接(查看源碼可發(fā)現(xiàn)有同步鎖鎖住資源,因此關閉流釋放鎖

public void close() throws IOException

三、三種read方法效率比較

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

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

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • Java Floyd算法求有權圖(非負權)的最短路徑并打印

    Java Floyd算法求有權圖(非負權)的最短路徑并打印

    這篇文章主要介紹了Java Floyd算法求有權圖(非負權)的最短路徑并打印,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-07-07
  • Java?批量生成條碼的示例代碼

    Java?批量生成條碼的示例代碼

    這篇文章主要介紹了Java?批量生成條碼的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-08-08
  • SpringSecurity整合JWT的使用示例

    SpringSecurity整合JWT的使用示例

    本文主要介紹了SpringSecurity整合JWT的使用示例,整合Spring?Security和JWT,可以使我們的應用程序更加安全和高效,感興趣的可以了解一下
    2023-11-11
  • mybatis解決<foreach>標簽不能超過1000的問題

    mybatis解決<foreach>標簽不能超過1000的問題

    MyBatis是一個開源的持久層框架,它可以幫助開發(fā)者簡化數(shù)據(jù)庫操作的編寫,而foreach是MyBatis中的一個重要標簽,用于在SQL語句中進行循環(huán)操作,本文主要給大家介紹了mybatis解決<foreach>標簽不能超過1000的問題,需要的朋友可以參考下
    2024-05-05
  • Java并發(fā)編程之StampedLock鎖介紹

    Java并發(fā)編程之StampedLock鎖介紹

    這篇文章主要介紹了Java并發(fā)編程之StampedLock鎖,StampedLock是并發(fā)包里面JDK8版本新增的一個鎖,下文更多相關內容需要的小伙伴可以參考一下
    2022-04-04
  • SpringSecurity中的表單認證詳細解析

    SpringSecurity中的表單認證詳細解析

    這篇文章主要介紹了SpringSecurity中的表單認證詳細解析,在上一篇文章中,我們初步引入了?Spring?Security,并使用其默認生效的?HTTP?基本認證保護?URL?資源,在本篇文章中我們使用表單認證來保護?URL?資源,需要的朋友可以參考下
    2023-12-12
  • 關于JVM垃圾回收的java.lang.ref.Finalizer問題

    關于JVM垃圾回收的java.lang.ref.Finalizer問題

    這篇文章主要介紹了關于JVM垃圾回收的java.lang.ref.Finalizer問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Spring和SpringMVC掃描注解類沖突的解決方案

    Spring和SpringMVC掃描注解類沖突的解決方案

    這篇文章主要介紹了Spring和SpringMVC掃描注解類沖突的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java SpringBoot詳解集成以及配置Swagger流程

    Java SpringBoot詳解集成以及配置Swagger流程

    Swagger 是一個規(guī)范和完整的框架,用于生成、描述、調用和可視化 RESTful 風格的 Web 服務??傮w目標是使客戶端和文件系統(tǒng)作為服務器以同樣的速度來更新。文件的方法,參數(shù)和模型緊密集成到服務器端的代碼,允許API來始終保持同步
    2021-10-10
  • 開發(fā)10年,全記在這本Java進階寶典里了

    開發(fā)10年,全記在這本Java進階寶典里了

    這篇文章主要給大家分享介紹了這本Java進階寶典里,是開發(fā)10年總結出來的,文中通過圖文介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧
    2019-04-04

最新評論

陆河县| 会同县| 清徐县| 荔波县| 东乌珠穆沁旗| 宜章县| 贡觉县| 太白县| 丰原市| 武邑县| 马公市| 罗平县| 美姑县| 达州市| 全南县| 麻阳| 若羌县| 富蕴县| 谢通门县| 左贡县| 怀远县| 神木县| 开封县| 新营市| 新干县| 洛隆县| 东乌珠穆沁旗| 贵州省| 方山县| 靖西县| 阿图什市| 岑溪市| 永寿县| 黑山县| 新津县| 府谷县| 浮山县| 五大连池市| 石渠县| 富民县| 绿春县|