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

java中的FileInputStream(輸入流)

 更新時間:2022年08月19日 10:06:04   作者:李昕羽  
這篇文章主要介紹了java中的FileInputStream(輸入流),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

一、File流概念

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

二、FileInputStream

1. FileInputStream概念

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

2. 構(gòu)造方法

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對象,還并未與計算機文件讀寫有關(guān)聯(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 {
? ? ? ? this(name != null ? new File(name) : null);
? ? }

該方法實際調(diào)用的還是上面那個方法。

3. 相關(guān)方法

3.1 public int read() throws IOException

官方文檔

public int read() throws IOException
從此輸入流中讀取一個數(shù)據(jù)字節(jié)。如果沒有輸入可用,則此方法將阻塞。 
指定者:
類 InputStream 中的 read
返回:
下一個數(shù)據(jù)字節(jié);如果已到達(dá)文件末尾,則返回 -1。 

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

  • 從輸入流中讀取一個字節(jié)返回int型變量,若到達(dá)文件末尾,則返回-1
  • 我們讀取的字節(jié)實際是由8位二進(jìn)制組成,二進(jìn)制文件不利于直觀查看,可以轉(zhuǎn)成常用的十進(jìn)制進(jìn)行展示,因此需要把讀取的字節(jié)從二進(jìn)制轉(zhuǎn)成十進(jìn)制整數(shù),故返回int型。
  • 如果當(dāng)文件未到底時,我們讀取的是字節(jié),若返回byte類型,那么勢必造成同一方法返回類型不同的情況這是不允許的
  • 既然說可以測試任意形式的文件,那么用兩種不同格式的,測試文件data1.txt和data2.txt,里面均放入1個數(shù)字"1",兩文件的格式分別為:ANSI和Unicode。

我們用如下代碼測試

import java.io.FileInputStream;
import java.io.IOException;
public class Test {
? ? public static void main(String[] args) throws IOException {
? ? ? ?
? ? ?FileInputStream fis = new FileInputStream("data1.txt");//ANSI格式
? ? ?for (int i = 0; i < 5; i++) {
? ? ? ? ?System.out.println(fis.read()); ? ?
? ? ?}
? ? ?
? ? ?fis.close(); ? ?
? ? ?System.out.println("------------------");
? ? ?fis = new FileInputStream("data2.txt");//Unicode格式
? ? ?for (int i = 0; i < 5; i++) {
? ? ? ? ?System.out.println(fis.read()); ? ?
? ? ?}
? ? ?fis.close();
? ? }
}

文件里不是只有一個數(shù)字嗎,為什么循環(huán)5次,什么鬼?稍后知曉,先看輸出結(jié)果:

49
-1
-1
-1
-1
------------------
255
254
49
0
-1

結(jié)果怎么會是這樣呢?

1.因為ANSI編碼沒有文件頭,因此數(shù)字字符1只占一個字節(jié),并且1的Ascii碼為49因此輸出49,而Unicode格式有2個字節(jié)的文件頭,并且以2個字節(jié)表示一個字符,對于Ascii字符對應(yīng)的字符則是第2位補0,因此1的Unicode碼的兩位十進(jìn)制分別為49和0;

附:文本文件各格式文件頭:ANSI類型:什么都沒有,UTF-8類型:EF BB BF,UNICODE類型:FF FE,UNICODE BIG ENDIAN類型:FE FF

2.從返回的結(jié)果來看,返回的是當(dāng)前的字節(jié)數(shù)據(jù),API文檔中原文為:“下一個數(shù)據(jù)字節(jié),如果已到達(dá)文件末尾,則返回 -1。”(英文原文為:the next byte of data, or -1 if the end of the file is reached),應(yīng)該理解成:此時的指針在下一個數(shù)據(jù)字節(jié)的開始位置。

3.2 read (byte[ ] b )

官方文檔

public int read(byte[] b) throws IOException
從此輸入流中將最多 b.length 個字節(jié)的數(shù)據(jù)讀入一個 byte 數(shù)組中。在某些輸入可用之前,此方法將阻塞。 
覆蓋:
類 InputStream 中的 read
參數(shù):
b - 存儲讀取數(shù)據(jù)的緩沖區(qū)。 
返回:
讀入緩沖區(qū)的字節(jié)總數(shù),如果因為已經(jīng)到達(dá)文件末尾而沒有更多的數(shù)據(jù),則返回 -1。 

解讀:

  • 最多b.length個字節(jié)的數(shù)據(jù)讀入一個byte數(shù)據(jù)組中,即,最多將byte數(shù)組b填滿;
  • 返回讀入緩沖的字節(jié)總數(shù),如果因為已經(jīng)到達(dá)文件末尾而沒有更多的數(shù)據(jù),則返回-1。這里即這為朋友的問題點,為什么用-1來判斷文件的結(jié)束。他的理由為,假設(shè)3個字節(jié)源數(shù)據(jù),用2個字節(jié)的數(shù)組來緩存,當(dāng)?shù)?次讀取的時候到達(dá)了文件的結(jié)尾,此時應(yīng)該返回-1了,豈不是只讀取到了2個字節(jié)?

同樣,我們來測試:

測試文件,data.txt,文件格式ANSI,文件內(nèi)容123,測試代碼:

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
public class Test {
    public static void main(String[] args) throws IOException {
     FileInputStream fis = new FileInputStream("data.txt");//ANSI格式
     byte[] b = new byte[2];
     for (int i = 0; i < 3; i++) {
         System.out.print("第"+(i+1)+"次讀取返回的結(jié)果:"+fis.read(b));
         System.out.println(",讀取后數(shù)組b的內(nèi)容為:"+Arrays.toString(b));
    }
     fis.close();
    }
}

輸出結(jié)果:

第1次讀取返回的結(jié)果:2,讀取后數(shù)組b的內(nèi)容為:[49, 50]
第2次讀取返回的結(jié)果:1,讀取后數(shù)組b的內(nèi)容為:[51, 50]
第3次讀取返回的結(jié)果:-1,讀取后數(shù)組b的內(nèi)容為:[51, 50]

測試數(shù)據(jù)文件采用的是ANSI格式,放入3個數(shù)字,因此為3個字節(jié),這里測試讀3次,從代碼中可以看出,b為一個byte數(shù)組,大小為2,即每次可以存放2個字節(jié)。那么問題來了,第一次讀取的時候讀到2個字節(jié)返回很好理解,而第2次的時候,由于只剩下一個字節(jié),此處到了文件的結(jié)尾,按照朋友對API文檔的理解,應(yīng)該返回-1才對?

讓我們看看源碼吧

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

晴天霹靂,是個被native修飾的方法,因此沒辦法繼續(xù)一步看代碼了。沒啥好說的,用個代碼類繼承FileInputStream,覆蓋read(byte b)方法,看代碼即能理解:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class MyFileInputStream extends FileInputStream{
? ? public MyFileInputStream(String name) throws FileNotFoundException {
? ? ? ? super(name);
? ? }
? ? @Override
? ? public int read(byte[] b) throws IOException {
? ? ? ? int getData = read();
? ? ? ? if (getData==-1) {
? ? ? ? ? ? return -1;
? ? ? ? }else{
? ? ? ? ? ? b[0] = (byte)getData;
? ? ? ? ? ? for (int i = 1; i < b.length; i++) {
? ? ? ? ? ? ? ? getData = read();
? ? ? ? ? ? ? ? if(-1==getData)
? ? ? ? ? ? ? ? ? ? return i;
? ? ? ? ? ? ? ? b[i] = (byte)getData;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return b.length;
? ? }
}

原測試代碼做小小的改動:

import java.io.FileInputStream;
import java.util.Arrays;
public class Test {
? ? public static void main(String[] args) throws Exception {
? ? ? ? FileInputStream fis = new MyFileInputStream("data.txt");//ANSI格式
? ? ? ? ?byte[] b = new byte[2];
? ? ? ? ?for (int i = 0; i < 3; i++) {
? ? ? ? ? ? ?System.out.print("第"+(i+1)+"次讀取返回的結(jié)果:"+fis.read(b));
? ? ? ? ? ? ?System.out.println(",讀取后數(shù)組b的內(nèi)容為:"+Arrays.toString(b));
? ? ? ? }
? ? ? ? ?fis.close();
? ? ? ? }
}

輸出結(jié)果與原結(jié)果一致:

第1次讀取返回的結(jié)果:2,讀取后數(shù)組b的內(nèi)容為:[49, 50]
第2次讀取返回的結(jié)果:1,讀取后數(shù)組b的內(nèi)容為:[51, 50]
第3次讀取返回的結(jié)果:-1,讀取后數(shù)組b的內(nèi)容為:[51, 50]

說明此方法內(nèi)部調(diào)用的是read()方法一個個的來讀數(shù)據(jù)。 如果第一個字節(jié)不是 -1 就會繼續(xù)讀,如果后續(xù)的read()返回的是-1 那么此方法就不會返回 - 1 返回的是i。

正確顯示文本內(nèi)容

import java.io.FileInputStream;
public class Test {
? ? public static void main(String[] args) throws Exception {
? ? ? ? FileInputStream fis = new MyFileInputStream("data.txt");//ANSI格式
? ? ? ? ?byte[] b = new byte[2];
? ? ? ? ?int len ;
? ? ? ? ?while (-1!=(len = fis.read(b))) {
? ? ? ? ? ? ?System.out.println(new String(b,0,len));
? ? ? ? }
? ? ? ? ?
? ? ? ? ?fis.close();
? ? ?}
}

3.3 available()方法

public int available();

方法的返回類型為int,它返回在解除阻塞期間可以從此FileInputStream讀取的剩余可用字節(jié)數(shù)。

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

相關(guān)文章

  • Java讀取.properties配置文件的幾種方式

    Java讀取.properties配置文件的幾種方式

    這篇文章主要介紹了Java讀取.properties配置文件的幾種方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • 解決Mybatis?mappe同時傳遞?List?和其他參數(shù)報錯的問題

    解決Mybatis?mappe同時傳遞?List?和其他參數(shù)報錯的問題

    在使用MyBatis時,如果需要傳遞多個參數(shù)到SQL中,可以遇到參數(shù)綁定問題,解決方法包括使用@Param注解和修改mapper.xml配置,感興趣的朋友跟隨小編一起看看吧
    2024-09-09
  • 實例講解Java基礎(chǔ)之反射

    實例講解Java基礎(chǔ)之反射

    今天小編就為大家分享一篇關(guān)于實例講解Java基礎(chǔ)之反射,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • 深入理解JAVA核心:揭秘反射機制的奧秘

    深入理解JAVA核心:揭秘反射機制的奧秘

    歡迎來到JAVA反射機制指南!想要了解如何在JAVA中實現(xiàn)靈活的編程技巧嗎?本指南將帶你揭開JAVA反射機制的神秘面紗,讓你的編程世界更加精彩!趕緊跟我一起來探索吧!
    2024-02-02
  • springboot jpa實現(xiàn)優(yōu)雅處理isDelete的默認(rèn)值

    springboot jpa實現(xiàn)優(yōu)雅處理isDelete的默認(rèn)值

    如果多個實體類都有 isDelete 字段,并且你希望在插入時為它們統(tǒng)一設(shè)置默認(rèn)值時改怎么做呢,本文為大家整理了一些方法,希望對大家有所幫助
    2024-11-11
  • log4j 詳解異步日志的配置和測試

    log4j 詳解異步日志的配置和測試

    這篇文章主要介紹了 log4j 詳解異步日志的配置和測試的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • Java利用MD5加鹽實現(xiàn)對密碼進(jìn)行加密處理

    Java利用MD5加鹽實現(xiàn)對密碼進(jìn)行加密處理

    在開發(fā)的時候,有一些敏感信息是不能直接通過明白直接保存到數(shù)據(jù)庫的。最經(jīng)典的就是密碼了。如果直接把密碼以明文的形式入庫,不僅會泄露用戶的隱私,對系統(tǒng)也是極其的不厲。本文就來和大家介紹一下如何對密碼進(jìn)行加密處理,感興趣的可以了解一下
    2023-02-02
  • 一文了解Java讀寫鎖ReentrantReadWriteLock的使用

    一文了解Java讀寫鎖ReentrantReadWriteLock的使用

    ReentrantReadWriteLock稱為讀寫鎖,它提供一個讀鎖,支持多個線程共享同一把鎖。這篇文章主要講解一下ReentrantReadWriteLock的使用和應(yīng)用場景,感興趣的可以了解一下
    2022-10-10
  • spring gateway如何解決跨域問題

    spring gateway如何解決跨域問題

    這篇文章主要介紹了spring gateway如何解決跨域問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • 輕量級聲明式的Http庫——Feign的獨立使用

    輕量級聲明式的Http庫——Feign的獨立使用

    這篇文章主要介紹了輕量級聲明式的Http庫——Feign的使用教程,幫助大家更好的理解和學(xué)習(xí)使用feign,感興趣的朋友可以了解下
    2021-04-04

最新評論

改则县| 中方县| 石首市| 岚皋县| 新民市| 紫云| 怀仁县| 健康| 乌拉特前旗| 林西县| 东宁县| 榆林市| 于田县| 昌宁县| 宾阳县| 扬中市| 东乌| 深水埗区| 车险| 新晃| 榆中县| 昭平县| 漠河县| 永年县| 澄江县| 长葛市| 山东| 峨山| 连城县| 察哈| 怀远县| 柳河县| 绵阳市| 昔阳县| 无为县| 儋州市| 保亭| 浦江县| 辰溪县| 盈江县| 海门市|