爲什麼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位。
*/
博客轉載地址: