简介
ByteArrayInputStream 字节数组输入流
上一篇简单的介绍了一下字节输入流的超类,只提及了一下超类中定义的一些方法;字节数组输入流是超类的一个具体的实现:主要的操作实际上就是读取操作一个字节数组,类中定义了一个缓冲的字节数组,具体的操作通过定义一下标志位,操作次数等进行读取该字节数组中的内容;
1.主要方法源码介绍
1.介绍过程依据第一篇中的描述的过程;
(1)首先介绍类中的属性内容:
//存放字节流数组,实际的操作的数据内容
protected byte buf[];
//当前读取的位置,在相关操作中会修改这个读取位置
protected int pos;
//标记读取的位置,如果有需要标记,可以使用mark()方法标记位置
protected int mark = 0;
//字节流数组大小
protected int count;
(2)然后是定义构造字节数组内容:该类提供了两种方式的构造函数;第一种直接指定字节数组输入流中缓冲的流数组,(这样后续的读取等操作都是在处理这个数组中的数据),该构造函数中设置了上面提到的相关属性;
第二种则指定了具体位置和大小,但实际的数据已全部在缓冲的数组中,只是确实了读取的位置和大小,所以可以读取的内容比实际的内容少;
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;
}
(3)判断是否还能读取:根据当前读取的位置来确定是否还有数据
public synchronized int available() {
return count - pos;
}
(4)具体的读取数据:读取操作及先判断满足读取条件后读取一个缓冲数组中的数据,并将读取位置+1,&0xff的意义在于保证数据操作的一致性(计算机存储数据机制方面)
public synchronized int read() {
return (pos < count) ? (buf[pos++] & 0xff) : -1;
}
读取数据到指定的字节数组中,可以指定读取的位置和大小
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;
}
(5)操作完记得关闭close();
2.其他方法简介:
1.skip()跳过,忽略:及修改读取位置
public synchronized long skip(long n) {
long k = count - pos;
if (n < k) {
k = n < 0 ? 0 : n;
}
pos += k;
return k;
}
2.mark():标记位置,操作过程中标记需要的位置,这样在后面可以通过reset()方法将读取位置修改到这个值,这样就可以再此从此位置读取数据;
public void mark(int readAheadLimit) {
mark = pos;
}
3.reset():上面介绍过了,
public synchronized void reset() {
pos = mark;
}
3.差不多就介绍完了,附上自己重写的代码
/**
1. 数组字节输入流
*/
public class MyByteArrayInputStream {
//存放字节流数组
protected byte buffer[];
//当前读取的位置
protected int position;
//字节流数组大小
protected int counts;
//标记读取的位置
protected int mark;
/**
* 指定字节数组构造输入流
* @param buf 指定数组
*/
public MyByteArrayInputStream(byte[] buf) {
this.buffer = buf;
this.counts = buf.length;
}
public MyByteArrayInputStream(byte[] buf,int offset,int length) {
this.position = offset;
this.mark = offset;
this.buffer = buf;
this.counts = Math.min(buf.length, length+offset);
}
//读取字节数组中的字节流
public synchronized int read(){
return position<counts ? buffer[position++] :-1;
}
//将数组中的字节流读入指定字节数组
public int read(byte[] buf,int offset,int length){
if(buf==null){
throw new NullPointerException("写入的数组为null");
}else if((offset<0)||(length<0)||(buf.length-offset<length)){
throw new IndexOutOfBoundsException("数组越界了");
}
//当前数组中的读取位置超出数组大小,则无数据可读
if(position>counts){
return -1;
}
//
int can = counts - position;
if(length > can){
length = can;
}
if(length <=0){
return 0;
}
System.arraycopy(buffer, position, buf, offset, length);
position += length;
return length;
}
//跳过字节数组中的n个字节
public synchronized long skip(long n){
//当前可读取的数量
long can = counts-position;
//当跳过的大小小于可读取的数量时
if(n < can){
//值大于0 设置跳过的次数为 n ,否则为0;
can = n < 0 ? 0 : n;
}
//设置当前读取的位置,跳过n个
position +=can;
//返回实际跳过的值
return can;
}
//是否支持标记,支持
public boolean markSupported(){
return true;
}
//标记当前读取的位置,与重置相对,标记之后,使用重置方法可以在指定位置读取
public void mark(){
mark = position;
}
//设置当前读取的位置为上一次标记的位置
public synchronized void reset(){
position = mark;
}
//剩余可以去到的数量
public synchronized int available(){
return counts-position;
}
//关闭操作
public void close() throws IOException {
}
}
## 4. 最后召唤神兽##
/**
* ___====-_ _-====___
* _--^^^#####// \\#####^^^--_
* _-^##########// ( ) \\##########^-_
* -############// |\^^/| \\############-
* _/############// (@::@) \\############\_
* /#############(( \\// ))#############\
* -###############\\ (oo) //###############-
* -#################\\ / VV \ //#################-
* -###################\\/ \//###################-
* _#/|##########/\######( /\ )######/\##########|\#_
* |/ |#/\#/\#/\/ \#/\##\ | | /##/\#/ \/\#/\#/\#| \|
* ` |/ V V ` V \#\| | | |/#/ V ' V V \| '
* ` ` ` ` / | | | | \ ' ' ' '
* ( | | | | )
* __\ | | | | /__
* (vvv(VVV)(VVV)vvv)
* 神兽保佑
* 代码无BUG!
*/
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。