1. 程式人生 > >java 程式設計下 IO 中的輸入流的 read() 方法返回值為什麼是 int 值

java 程式設計下 IO 中的輸入流的 read() 方法返回值為什麼是 int 值

Java 下 IO 中 FileReder 和 FileInputStream 分別是以字元和位元組的形式來完成資料的讀取的,然而返回值確是 int 型別的資料,這樣做的核心目的只是要取到到一個 int 型別下的 -1 來表示資料流的末尾。為什麼要這樣做?又是怎麼實現的呢?

首先看 FileReder :

FileReader fr = new FileReader("src.txt");
int ch = fr.read();

如上面的程式碼,FileReader 的 read 方法返回值是一個 int 型別的變數來接收的,然而 read 方法在實際中卻是以字元形式來進行資料的讀取的。通過上面的基本資料型別的取值範圍我們能發現 char 型別資料的取值範圍為 0 ~ 65535 ,也就是說 char 型別資料是取不到負值的;int 型別資料的取值範圍為 -2147483648 ~ 2147483647 ,可以取到負值;同時 int 的取值範圍又包含 char 的取值範圍,這就為使用 int 作為返回值型別提供了可能,因為流需要一個特殊的值來表示流末尾,這個值不應該在 char 的取值範圍內,如果使用 char 取值範圍內的值作為流末尾標誌,那麼這個值同樣有可能出現在資料流中間作為資料來傳輸,流在讀到這個值的時候會認為已經到達流末尾,後面未讀取的資料將被截斷。所以 Java 中選擇了使用 -1 來作為流末尾,這個值不在 char 的取值範圍內,所以不存在資料截斷,然而 -1 又在 int 的取值範圍內,同時 int 的取值範圍包含 char 的取值範圍,所以 FileReader 下 read 方法返回的 char 型別資料直接轉為了 int 型別。

再看 FileInputStream :

FileInputStream fis = new FileInputStream("src.txt");
int b = fis.read();

同理 FileInputStream 也需要一個自己取不到的值來作為流末尾的標誌,Java 同樣使用 -1 來作為位元組流的流末尾,從上面基本資料型別的取值範圍我們可以看到 byte 的取值範圍為 -128 ~ 127 ,這就意味走著 byte 可以取到 -1 ,如果把 -1 直接當作 int 作為流末尾,那麼就無法區分這個讀到的結果是流末尾還是流中的資料了,那麼 Java 是如何實現取值 -1 的呢?在 Java 內部,Java 通過高位補 0 來實現資料從 byte 到 int 的轉換,舉個例子:

-1 在 byte 型別和 int 型別中都可以取到,-1 在 byte 型別下的二進位制儲存形式為 11111111 ,然而使用 read 方法的時候,Java 內部將 byte 的高位補 0 將 byte 轉為 int 型別,所以 byte 型別的 -1 在 int 型別下的二進位制儲存形式為 00000000 00000000 00000000 11111111,對應的 int 值為 255,通過高位補 0 ,所有 byte 型別的負數都轉為了正數。然而在使用這些讀到的 byte 資料時,只要將這些資料從 int 強轉回 byte 即可得到原有的資料。所以就可以使用 -1 來作為流末尾的標誌,因為 Java 內部將 byte 的負數通過高位補 0 將其轉換為了負數。

原文出處:https://blog.csdn.net/ZJDWHD/article/details/50908626