Java 字節讀取流的read方法返回int的原因

爲什麼InputStream.read()讀取一個byte確返回一個int呢?

java 字節讀取流的read方法一次讀一個byte但返回int的原因

讀取二進制數據按字節讀取,每次讀一個字節(byte)。

read()的底層是由C++實現的,返回的是unsigned byte,取值範圍爲[0~255],在java中沒有對應的類型,所以只能用int類型接收,由Java接收得到的就是int[0、255]。

在java中byte只能表示[0-127]的無符號數。也對應這java中int[0-127]

那麼[128-255]怎麼表示?

在java中byte的範圍是[-128,127],所以[128-255]只能由int來接收。

使用-128 & 0xff = 128

    -127 & 0xff = 129

      -1 & 0xff = 255

就把byte提升爲int類型了,來表示數據。

---------------------------

在讀取一個字節數據時,容易出現連續8個1的情況,連續8個1是-1, 正好符合了流結束標記。

所以要轉換數據,將讀到的字節進行int類型的提升。保留該字節數據的同時,前面都補0,避免-1的情況。

11111111------->0000 0000 1111 1111

   -1    &  0xff   =     255

因此java 字節讀取流的read方法一次讀一個byte就會返回int。

----------------------------

在使用字節輸出流的write方法寫入的時候,其實內部將int強轉一下,還原成原來的byte字節數據。。

(byte)128 = -128

 

(byte)129 = -127

 

(byte)255 = -1

0000 0000 1111 1111--->1111 1111

-------------------------

舉例這麼說:

FileInputStream的read方法在做類型提升(將byte提升爲int)

FileOutputStream的write的方法在做類型強轉(將int強轉爲byte)

 

import java.io.*;
 
class MyBufferedInputStream
{
    private InputStream in;
 
    private byte[] buf = new byte[1024*4];
 
    private int pos = 0;//用於操作數組元素的指針(索引,角標)。
    private int count = 0;//記錄住每一次往數組中存儲的元素個數。
    MyBufferedInputStream(InputStream in)
    {
        this.in = in;
    }
    /*
    爲什麼,字節讀取流的read方法一次讀一個字節,返回值類型,不是byte,而是int呢?
    那是因爲,在讀取一個字節數據時,容易出現連續8個1的情況,連續8個1是-1.
    正好符合了流結束標記。所以爲了避免,流操作數據是提前結束,
    將讀到的字節進行int類型的提升。保留該字節數據的同時,前面都補0.避免-1的情況。
    */
    
    //一次讀一個字節,從緩衝區(字節數組)獲取。
    public int myRead()throws IOException
    {
    //通過in對象讀取硬盤上數據,並存儲buf中。
        if(count==0)
        {
            count = in.read(buf);
            if(count<0)
                return -1;
 
            pos = 0;
            byte b = buf[pos];
            
            pos++;
            count--;
 
            return b&255;
        }
        else if(count>0)
        {
            byte b = buf[pos];
            pos++;
            count--;
            return b&0xFF;
        }
 
        return -1;
    }
    public void myClose()throws IOException
    {
        in.close();
    }
 
//=========調用以上類======
    public static void copyMp3()throws IOException
    {
        MyBufferedInputStream bufis = new MyBufferedInputStream(new FileInputStream("c:\\0.mp3"));
 
        BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\6.mp3"));
 
        int temp = 0;
 
        while((temp=bufis.myRead())!=-1)
        {
            bufos.write(temp);//輸出流的write方法雖然接收是一個整數,四個字節,但是write只將最後一個字節寫出。
                            //其他字節拋棄。
        }
        bufos.close();
        bufis.myClose();
    }
}
 
/*
結論:
字節流的讀一個字節的read方法爲什麼返回值類型不是byte,而是int。
因爲有可能會讀到連續8個二進制1的情況,8個二進制1對應的十進制是-1.
那麼就會數據還沒有讀完,就結束的情況。因爲我們判斷讀取結束是通過結尾標記-1來確定的。
所以,爲了避免這種情況將讀到的字節進行int類型的提升。
並在保留原字節數據的情況前面了補了24個0,變成了int類型的數值。
而在寫入數據時,只寫該int類型數據的最低8位。
*/

博客轉載地址:

java基礎--Java 字節讀取流的read方法返回int的原因

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章