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! */
相关文章推荐
- java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)
- JAVA IO源码学习系列之InputStream
- java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)
- JAVA IO源码学习系列一(ByteArrayOutputStream)
- java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)
- java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)
- JAVA IO源码学习系列一(OutputStream)
- JDK 1.7 java.io 源码学习之ByteArrayInputStream和ByteArrayOutputStream
- Java IO 系列源码分析——ByteArrayInputStream和ByteArrayOutputStream
- java io系列04之 管道(PipedOutputStream和PipedInputStream)的简介,源码分析和示例
- Java IO学习【12】字节流byte Stream的基本write/read学习
- java io系列15之 DataOutputStream(数据输出流)的认知、源码和示例
- Java 学习系列: IO相关的BIO,NIO与AIO
- java io系列03之 ByteArrayOutputStream的简介,源码分析和示例(包括OutputStream)
- Java 源码学习线路————_先JDK工具包集合_再core包,也就是String、StringBuffer等_Java IO类库
- java io系列14之 DataInputStream(数据输入流)的认知、源码和示例
- Java 7 源码学习系列(三)——BigInteger
- java io系列03之 ByteArrayOutputStream的简介,源码分析和示例(包括OutputStream)
- java io系列12之 BufferedInputStream(缓冲输入流)的认知、源码和示例
- Java IO系列1 字节流之ByteArrayInputStream与ByteArrayOutputStream