您的位置:首页 > 编程语言 > Java开发

JAVA IO源码学习系列之ByteArrayInputStream

2017-11-14 18:42 471 查看

简介

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!
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐