ByteArrayInputStream的源码解析

本文介绍了ByteArrayInputStream的基本概念,包括其继承关系、内部结构、构造方法及常用API。ByteArrayInputStream是一种特殊的输入流,它直接从内存中的字节数组读取数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ByteArrayInputStream是字节数组输入流,继承于InputStream,
已经实现的接口:Closeable;

继承关系:

class ByteArrayInputStream extends InputStream {
  • ByteArrayInputStream 包含一个内部缓冲区,该缓冲区包含从流中读取的字节。通俗点讲,它的内部缓冲区就是一个字节数组,而ByteArrayInputStream本质就是通过字节数组来实现的;
  • InputStream是通过read()方法向外提供接口,供它们来读取字节数据;而ByteArrayInputStream的内部额外的定义了一个计数器,用来跟踪read()方法要读取的下一个字节。
  • 关闭 ByteArrayInputStream 无效。
  • 此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException
    它包含一个内部缓冲区,该缓冲区包含从流中读取的字节;

属性:

protected byte[] buf: 存储输入流中的字节数组

protected int count: 输入流中字节的个数,比输入流缓冲区中最后一个有效字符的索引大一的索引。此值应该始终是非负数,并且不应大于 buf 的长度。它比 buf 中最后一个可从输入流缓冲区中读取的字节位置大一。

protected int mark: 流中当前的标记位置

protected int pos: 要从输入流缓冲区中读取的下一个字节的索引

构造函数:

ByteArrayInputStream(byte[] buf);  
  
创建一个ByteArrayInputStream实例,使用字节数组buf作为其缓冲区数组。

ByteArrayInputStream(byte[] buf,int offset,int length);

创建一个ByteArrayInputStream实例,使用字节数组buf从offset开始的len个字节作为其缓冲区数组。

创建 ByteArrayInputStream,使用 buf 作为其缓冲区数组。 

pos 的初始值是 offset, 

count 的初始值是 offset+length 和 buf.length 中的最小值。

该缓冲区数组不是复制得到的。将该缓冲区的标记设置为指定的偏移量。

参数:
buf - 输入缓冲区。
offset - 缓冲区中要读取的第一个字节的偏移量。
length - 从缓冲区中读取的最大字节数。主要方法:

主要方法:

int available(): 输入流中可读取的字节个数

void close(): 关闭此输入流并释放与该流有关的系统资源.

void mark(int readlimit): 在此输入流中标记当前的位置.

boolean markSupported(): 检测此输入流是否支持mark和reset.

int read(): 从输入流中读取下一个字节数据.

int read(byte[] b,int off,int len): 从输入流中读取len个字节,并将其存储在字节数组b中off位置开始的地方

void reset(): 将此流重新定位到最后一次对此输入流调用mark方法时的位置.

long skip(long n): 跳过和丢弃此输入流中n个字节的数据.

源码解析

//构造函数
public ByteArrayInputStream(byte buf[]) {
    this.buf = buf;
    this.pos = 0;
    this.count = buf.length;
}

public ByteArrayInputStream(byte buf[], int offset, int length) {
    this.buf = buf;
    this.pos = offset;
    this.count = Math.min(offset + length, buf.length);
    this.mark = offset;
}
创建 ByteArrayInputStream,使用 buf 作为其缓冲区数组。 
pos 的初始值是 offset, count 的初始值是 offset+length 
和 buf.length 中的最小值。该缓冲区数组不是复制得到的。
将该缓冲区的标记设置为指定的偏移量。
参数:
buf - 输入缓冲区。
offset - 缓冲区中要读取的第一个字节的偏移量。
length - 从缓冲区中读取的最大字节数。

方法介绍:

//从输入流中读取下一个字节数据.
 public synchronized int read() {
        return (pos < count) ? (buf[pos++] & 0xff) : -1;
    }
 //count  比输入流缓冲区中最后一个有效字符的索引大一的索引。 
    
 // 从输入流中读取len个字节,并将其存储在字节数组b中off位置开始的地方
 //将最多 len 个数据字节从此输入流读入 byte 数组。
 //如果pos等于count,则返回-1;指示文件结束;否则,读取的字节数 k 等于 len 和 count-pos 中的较小者。
//如果 k 是正数,则以 System.arraycopy 执行的方式,将 buf[pos] 到 buf[pos+k-1] 的字节复制 b[off] 到 b[off+k-1] 中。将值 k 与 pos 相加并返回 k。        
 public synchronized int read(byte b[], int off, int len) {
        if (b == null) {
            throw new NullPointerException();
        } else if (off < 0 || len < 0 || len > b.length - off) {
            throw new IndexOutOfBoundsException();
        }

        if (pos >= count) {
            return -1;
        }

        int avail = count - pos;
        if (len > avail) {
            len = avail;
        }
        if (len <= 0) {
            return 0;
        }
        System.arraycopy(buf, pos, b, off, len);
        pos += len;
        return len;
    }
//从此输入流中跳过 n 个输入字节。如果已到达输入流末尾,
//则可能会跳过较少的字节。
//实际跳过的字节数 k 等于 n 和 count-pos 中的较小者。
//将值 k 与 pos 相加并返回 k。
public synchronized long skip(long n) {
    long k = count - pos;
    if (n < k) {
        k = n < 0 ? 0 : n;
    }

    pos += k;
    return k;
}

// 输入流中可读取的字节个数
//返回可从此输入流读取(或跳过)的剩余字节数。
//返回值是 count - pos,它是要从输入缓冲区中读取的剩余字节数。
public synchronized int available() {
    return count - pos;
}

//检测此输入流是否支持mark和reset.
public boolean markSupported() {
    return true;
    }
    
/**
在此输入流中标记当前的位置.
流中当前的标记位置。构造时默认将 ByteArrayInputStream 对象
标记在位置零处。通过 mark() 方法可将其标记在缓冲区内的另一个位置处。
通过 reset() 方法将当前缓冲区位置设置为此点。
*/    
public void mark(int readAheadLimit) {
        mark = pos;
    }

//将此流重新定位到最后一次对此输入流调用mark方法时的位置.
//将缓冲区的位置重置为标记位置。除非已标记了另一个位置,
//或者在构造方法中指定了一个偏移量,否则该标记位置是 0。
public synchronized void reset() {
        pos = mark;
    }    

 
  public void close() throws IOException {
    }                                              
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值