大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 學習攻略 Java學習 Java輸入流的介紹

Java輸入流的介紹

更新時間:2022-10-26 10:32:20 來源:動力節點 瀏覽1052次

InputStream就是Java標準庫提供的最基本的輸入流。它位于java.io這個包里。java.io包提供了所有同步IO的功能。

要特別注意的一點是,InputStream并不是一個接口,而是一個Java抽象類,它是所有輸入流的超類。這個抽象類定義的一個最重要的方法就是int read(),簽名如下:

public abstract int read() throws IOException;

這個方法會讀取輸入流的下一個字節,并返回字節表示的int值(0~255)。如果已讀到末尾,返回-1表示不能繼續讀取了。

FileInputStream是InputStream的一個子類。顧名思義,FileInputStream就是從文件流中讀取數據。下面的代碼演示了如何完整地讀取一個FileInputStream的所有字節:

public void readFile() throws IOException {
    // 創建一個FileInputStream對象:
    InputStream input = new FileInputStream("src/readme.txt");
    for (;;) {
        int n = input.read(); // 反復調用read()方法,直到返回-1
        if (n == -1) {
            break;
        }
        System.out.println(n); // 打印byte的值
    }
    input.close(); // 關閉流
}

在計算機中,類似文件、網絡端口這些資源,都是由操作系統統一管理的。應用程序在運行的過程中,如果打開了一個文件進行讀寫,完成后要及時地關閉,以便讓操作系統把資源釋放掉,否則,應用程序占用的資源會越來越多,不但白白占用內存,還會影響其他應用程序的運行。

InputStream和OutputStream都是通過close()方法來關閉流。關閉流就會釋放對應的底層資源。

我們還要注意到在讀取或寫入IO流的過程中,可能會發生錯誤,例如,文件不存在導致無法讀取,沒有寫權限導致寫入失敗,等等,這些底層錯誤由Java虛擬機自動封裝成IOException異常并拋出。因此,所有與IO操作相關的代碼都必須正確處理IOException。

仔細觀察上面的代碼,會發現一個潛在的問題:如果讀取過程中發生了IO錯誤,InputStream就沒法正確地關閉,資源也就沒法及時釋放。

因此,我們需要用try ... finally來保證InputStream在無論是否發生IO錯誤的時候都能夠正確地關閉:

public void readFile() throws IOException {
    InputStream input = null;
    try {
        input = new FileInputStream("src/readme.txt");
        int n;
        while ((n = input.read()) != -1) { // 利用while同時讀取并判斷
            System.out.println(n);
        }
    } finally {
        if (input != null) { input.close(); }
    }
}

用try ... finally來編寫上述代碼會感覺比較復雜,更好的寫法是利用Java 7引入的新的try(resource)的語法,只需要編寫try語句,讓編譯器自動為我們關閉資源。推薦的寫法如下:

public void readFile() throws IOException {
    try (InputStream input = new FileInputStream("src/readme.txt")) {
        int n;
        while ((n = input.read()) != -1) {
            System.out.println(n);
        }
    } // 編譯器在此自動為我們寫入finally并調用close()
}

實際上,編譯器并不會特別地為InputStream加上自動關閉。編譯器只看try(resource = ...)中的對象是否實現了java.lang.AutoCloseable接口,如果實現了,就自動加上finally語句并調用close()方法。InputStream和OutputStream都實現了這個接口,因此,都可以用在try(resource)中。

緩沖

在讀取流的時候,一次讀取一個字節并不是最高效的方法。很多流支持一次性讀取多個字節到緩沖區,對于文件和網絡流來說,利用緩沖區一次性讀取多個字節效率往往要高很多。InputStream提供了兩個重載方法來支持讀取多個字節:

int read(byte[] b):讀取若干字節并填充到byte[]數組,返回讀取的字節數

int read(byte[] b, int off, int len):指定byte[]數組的偏移量和最大填充數

利用上述方法一次讀取多個字節時,需要先定義一個byte[]數組作為緩沖區,read()方法會盡可能多地讀取字節到緩沖區, 但不會超過緩沖區的大小。read()方法的返回值不再是字節的int值,而是返回實際讀取了多少個字節。如果返回-1,表示沒有更多的數據了。

利用緩沖區一次讀取多個字節的代碼如下:

public void readFile() throws IOException {
    try (InputStream input = new FileInputStream("src/readme.txt")) {
        // 定義1000個字節大小的緩沖區:
        byte[] buffer = new byte[1000];
        int n;
        while ((n = input.read(buffer)) != -1) { // 讀取到緩沖區
            System.out.println("read " + n + " bytes.");
        }
    }
}

阻塞

在調用InputStream的read()方法讀取數據時,我們說read()方法是阻塞(Blocking)的。它的意思是,對于下面的代碼:

int n;
n = input.read(); // 必須等待read()方法返回才能執行下一行代碼
int m = n;

執行到第二行代碼時,必須等read()方法返回后才能繼續。因為讀取IO流相比執行普通代碼,速度會慢很多,因此,無法確定read()方法調用到底要花費多長時間。

InputStream實現類

用FileInputStream可以從文件獲取輸入流,這是InputStream常用的一個實現類。此外,ByteArrayInputStream可以在內存中模擬一個InputStream:

public class Main {
    public static void main(String[] args) throws IOException {
        byte[] data = { 72, 101, 108, 108, 111, 33 };
        try (InputStream input = new ByteArrayInputStream(data)) {
            int n;
            while ((n = input.read()) != -1) {
                System.out.println((char)n);
            }
        }
    }
}

ByteArrayInputStream實際上是把一個byte[]數組在內存中變成一個InputStream,雖然實際應用不多,但測試的時候,可以用它來構造一個InputStream。

舉個栗子:我們想從文件中讀取所有字節,并轉換成char然后拼成一個字符串,可以這么寫:

public class Main {
    public static void main(String[] args) throws IOException {
        String s;
        try (InputStream input = new FileInputStream("C:\\test\\README.txt")) {
            int n;
            StringBuilder sb = new StringBuilder();
            while ((n = input.read()) != -1) {
                sb.append((char) n);
            }
            s = sb.toString();
        }
        System.out.println(s);
    }
}

要測試上面的程序,就真的需要在本地硬盤上放一個真實的文本文件。如果我們把代碼稍微改造一下,提取一個readAsString()的方法:

public class Main {
    public static void main(String[] args) throws IOException {
        String s;
        try (InputStream input = new FileInputStream("C:\\test\\README.txt")) {
            s = readAsString(input);
        }
        System.out.println(s);
    }
    public static String readAsString(InputStream input) throws IOException {
        int n;
        StringBuilder sb = new StringBuilder();
        while ((n = input.read()) != -1) {
            sb.append((char) n);
        }
        return sb.toString();
    }
}

對這個String readAsString(InputStream input)方法進行測試就相當簡單,因為不一定要傳入一個真的FileInputStream:

public class Main {
    public static void main(String[] args) throws IOException {
        byte[] data = { 72, 101, 108, 108, 111, 33 };
        try (InputStream input = new ByteArrayInputStream(data)) {
            String s = readAsString(input);
            System.out.println(s);
        }
    }
    public static String readAsString(InputStream input) throws IOException {
        int n;
        StringBuilder sb = new StringBuilder();
        while ((n = input.read()) != -1) {
            sb.append((char) n);
        }
        return sb.toString();
    }
}

這就是面向抽象編程原則的應用:接受InputStream抽象類型,而不是具體的FileInputStream類型,從而使得代碼可以處理InputStream的任意實現類。如果大家想了解更多相關知識,可以關注一下本站的Java在線學習,里面的課程內容由淺到深,細致全面,很適合沒有基礎的小伙伴學習,希望對大家能夠有所幫助哦。

提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 四虎影库网址 | 国产伦精品一区二区三区女 | 精品国产免费一区二区三区五区 | 欧美性色xo影院在线观看 | 国产特级毛片aaaaaaa高清 | 久久99国产精品久久欧美 | 国产美女一级视频 | 特级生活片| 国产欧美精品午夜在线播放 | 精品视频免费在线 | 久久精品国产亚洲麻豆 | 免费视频日韩 | 9999在线观看 | 狠狠狠色丁香婷婷综合久久五月 | 久久国内精品自在自线400部o | 台湾一级毛片永久免费 | 欧美一级高清视频在线播放 | 国产精品爱久久久久久久9999 | 91成人精品视频 | 国产va免费精品 | 日韩永久免费视频 | 一级在线 | 欧洲 | 欧美日韩中文字幕一区二区高清 | 色综合五月激情综合色一区 | 狠狠色丁香久久婷婷综 | 国产一区二区三区四区 | 99在线观看精品免费99 | 在线成人天天鲁夜啪视频 | 视频二区 素人 欧美 日韩 | 欧美va放荡人妇大片 | 久久久久久久网 | 亚洲综合专区 | 91精品国产高清91久久久久久 | 97色老99久久九九爱精品 | 91视频专区| 老司机免费精品视频 | 亚洲天堂久久精品成人 | 国产成人精品magnet | 国产乱人伦精品一区二区 | 国产日韩欧美自拍 | 不卡伦理|