亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術文章
文章詳情頁

Java使用FileInputStream流讀取文件示例詳解

瀏覽:4日期:2022-08-28 17:06:58

一、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:UsersAdministratorDesktop1.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:UsersAdministratorDesktop1.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:UsersAdministratorDesktop1.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流讀取文件示例詳解的文章就介紹到這了,更多相關Java FileInputStream流讀取文件內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Java
相關文章:
主站蜘蛛池模板: 精品在线视频免费 | 97精品国产自在现线免费 | 麻豆视频免费在线观看 | 免费黄色高清视频 | 国产免费叼嘿视频 | 日本欧美韩国一区二区三区 | 日韩一级特黄毛片在线看 | 播放中国女人毛片一级带 | 久久久国产99久久国产久 | 一级特黄录像绵费播放 | 最新99国产成人精品视频免费 | 五月天婷婷综合 | 欧美人成人亚洲专区中文字幕 | 伊人亚洲综合网成人 | 黄色大片黄色大片 | 国产精品二区三区免费播放心 | 玖玖精品视频 | 97国产伦子在线观看 | 日韩一区二区三区在线视频 | 国产一二精品 | 中国一级毛片视频 | 宅男午夜剧场 | 一节毛片 | 国产高清黄色 | 婷婷丁香啪啪 | 六月婷婷精品视频在线观看 | www视频在线播放 | 不卡中文字幕在线观看 | 高清不卡日本v在线二区 | 国产精品亚洲综合 | 亚洲精品色综合色在线观看 | 国产高清视频一区二区 | 自怕偷自怕亚洲精品 | 国产在热线精品视频国产一二 | 青青草社区 | 日韩国产欧美在线观看 | 亚洲国产经典 | 国产大秀视频一区二区三区 | 欧美色爱综合网 | 国产超薄肉色丝袜的免费网站 | 欧美日本韩国一区 |