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的原因

猜你喜欢

转载自blog.csdn.net/yu532164710/article/details/88409562