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

05JavaIO详解_仿照IO源码自己去实现一个IO流(为了加深印象,本身没有价值)

2016-08-05 16:46 471 查看
版本会越来越难:

版本1:只写一个read方法

package com.guigu.shen.InputStream;

import java.io.IOException;
import java.io.InputStream;

import javax.print.attribute.PrintRequestAttribute;

//包含main方法。用来做测试的。
public class MyStream {

public static void main(String[] args) throws Exception {

byte[] b=new byte[16];
for(int i=0;i<b.length;i++)
{

b[i]=(byte)i;

}
MybyteArrayInputStream mybyteArrayInputStream=new MybyteArrayInputStream(b);
//死循环,直到把数据读完
while(true)
{
int c=mybyteArrayInputStream.read();
if(c<0)
{
break;

}
System.out.println(c+" ");
}

}

}
class MybyteArrayInputStream extends InputStream
{
//存放要被读取的数据的索引
private byte[] data;
//当前读的位置
private int ptr=0;
//这个构造函数传进来的就是我们要去读取的数据。
public MybyteArrayInputStream(byte[] b) {
//把要读的数据的索引赋给data;
this.data=b;

}
//每一次读取一个字节,没有读到返回-1;
@Override
public int read() throws IOException {
//看data里面的数据有没有被读完,没有读完(<data.length)就返回里面的值,读完了,就返回-1;

return (ptr<data.length)?(data[ptr++]):-1;
}

}
结果:1,2,3,4,5,6、、、、、、15


版本2:有2个read方法。重写了InputStream里面很多方法,基本完整了。

package com.guigu.shen.InputStream;

import java.io.IOException;
import java.io.InputStream;

public class MyStream2  extends InputStream{
protected byte[] data;
//表示我当前读到的位置
protected int ptr=0;
//表示记住位置,我下一次可以跳到这个位置上
protected int mark=0;
public MyStream2(byte[] b) {
this.data=b;
}
@Override
public int read()
{
return (ptr<data.length)?(data[ptr++]):-1;

}
//这个方法返回的是我还有几个数据没有读
@Override
public int available() throws IOException {
//this.data.length表示我要读的数据额长度,ptr表示我已经读到哪里了,两者相减就是还剩下多少没有读
return this.data.length-ptr;
}
@Override
public void close() throws IOException {
//表明我读到最后了
ptr=data.length;
}
//表示我下次可以跳到这个位置上
@Override
public synchronized void mark(int readlimit) {
this.mark=readlimit;
}
//这个方法表示,我调用这个方法呢,就可以回到mark这个位置上。
@Override
public synchronized void reset() throws IOException {

if(mark<0||mark>=data.length)
{

throw new IOException("the postion is not valid");

}
ptr=mark;

}
//要想使用mark这个功能,就要让这个函数返回ture
@Override
public boolean markSupported() {
return true;
}
//重写第三个read方法,这个方法会调用第一个read()方法
@Override
public int read(byte[] b, int off, int len) throws IOException {

//如果已经读到末尾了或者长度小于0,就不行
if(this.ptr>=data.length||len<0)
{
return -1;

}
//如果已经读到了ptr,你还要读len这么长,当ptr+len>数据总长度时是不合理的。
if((this.ptr+len)>data.length)
{

//读取剩下的就好了
len=data.length-this.ptr;

}
if(len==0)
{
return 0;

}
/*
*
* System提供了一个静态方法arraycopy(),我们可以使用它来实现数组之间的复制。
* 其函数原型是: public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
* src:源数组; srcPos:源数组要复制的起始位置; dest:目的数组; destPos:目的数组放置的起始位置; length:复制的长度。
*  注意:src and dest都必须是同类型或者可以进行转换类型的数组.
*
*
*/

//把data数据里面的数据从ptr这个位置开始共len长度拷贝到b这个数组中的off这个位置开始的位置。同过数组拷贝的方式把数组拷贝到外面
System.arraycopy(data, ptr, b, off, len);
//更新已经读到的位置
ptr+=len;
//返回实际读到的长度
return len;

}

}


到这里,字节流讲完了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐