InputStream解读

来源:互联网 发布:淘宝联盟佣金怎么提现 编辑:程序博客网 时间:2024/06/05 16:02

首先说说

public abstract int read() throws IOException

,这个read方法返回的是一个unsigned的byte,范围是0-255.而java中不存在unsigned的byte类型,所以要用int来存放。而用int存放的其实只是unsigned byte的模拟实现

比如:

int[] data = new int[10];

for (int i = 0; i < data.length; i++) {

data[i] = System.in.read();

}

而如果使用byte数组,比如

byte[] b = new byte[10];

for (int i = 0; i < b.length; i++) {

b[i] = (byte) System.in.read();

}

byte数组里存放的是有符号数,范围-128~127

如果要将有符号数转回无符号数,那么可以通过公式

int i = (b >= 0) ? b : 256 + b;

也可以通过b&&0xff来实现,

这其实是一个int  byte转换的问题,java中的int和byte都是有符号数,当byte扩展为int时,自动添加位,比如

转换前 11010110  (有符号数 -42)

(转换,牵涉到符号位的扩展。因为扩展前符号位是1,所以扩展后,高位都是1)

转换后 11111111 11111111 11111111  11010110 (- 42),所以不变。

而当int转换成byte时,会采取截断前24位留下末尾8位的策略。当int的数值范围在-127~128时,截断不会产生任何影响,所以转换出来的byte与原始值一样。

 再来看

public int read (byte b[] , int  i, int j)

public int read(byte abyte0[], int i, int j)        throws IOException    {        if(abyte0 == null)            throw new NullPointerException();        if(i < 0 || j < 0 || j > abyte0.length - i)            throw new IndexOutOfBoundsException();        if(j == 0)            return 0;        int k = read();        if(k == -1)            return -1;        abyte0[i] = (byte)k;        int i1 = 1;        do        {            try            {                if(i1 >= j)                    break;                int l = read();                if(l == -1)                    break;                abyte0[i + i1] = (byte)l;                i1++;                continue;            }            catch(IOException ioexception) { }            break;        } while(true);        return i1;    }


 

参数i代表的是byte b[]的偏移量,说明从第i个位置开始赋值,j代表的是读取的字节数。

这个方法会先尝试着read()读取一个byte,如果恰好读到末尾,则返回-1。若没有读到末尾,便开始循环调用read()方法进行读取,并记录下读取的字节数。

所以,当此方法返回-1时,说明已经读取到末尾了。

 最后看

public long skip(long l)

 public long skip(long l)        throws IOException    {        long l1 = l;        if(l <= 0L)            return 0L;        int j = (int)Math.min(2048L, l1);        byte abyte0[] = new byte[j];        do        {            if(l1 <= 0L)                break;            int i = read(abyte0, 0, (int)Math.min(j, l1));            if(i < 0)                break;            l1 -= i;        } while(true);        return l - l1;    }


 

该方法首先比较l和2048,选出较小的数作为byte b[]的长度。假设l大于2048,则j=2048,数组长度为2048,循环中每次都会读取2048个字节,并从l1中扣除读取到的2048个字节,现在考虑两种情况:1,不会读到末尾。那么某一时刻,l1会小于2048,那么只需再读取l1个字节就退出循环。2,会读取到末尾。此时,会先读取到末尾,然后在下一次的循环时i为-1,跳出循环。

skip方法返回实际跳过的字节数。

 

 

 

 

 

 

 

0 0
原创粉丝点击