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

版本会越来越难:

版本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;

}

}

到这里,字节流讲完了

时间: 2024-10-19 10:25:29

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

[Android]Toolbar使用详解(三)——源码解析

更多关于Toolbar的使用请移步Toolbar使用详解系列 从Toolbar的使用一步步解析Toolbar源码 大体架构 API 0.设置导航图标 mToolbar.setNavigationIcon(R.drawable.ic_actionbar_flow); 源码如下 public void setNavigationIcon(int resId) { this.setNavigationIcon(this.mTintManager.getDrawable(resId)); } setNa

微信小程序 授权登录详解(附完整源码)

一.前言 由于微信官方修改了 getUserInfo 接口,所以现在无法实现一进入微信小程序就弹出授权窗口,只能通过 button 去触发. 官方连接:https://developers.weixin.qq.com/community/develop/doc/0000a26e1aca6012e896a517556c01 二.实现思路 自己写一个微信授权登录页面让用户实现点击的功能,也就是实现了通过 button 组件去触发 getUserInof 接口.在用户进入微信小程序的时候,判断用户是否

干货:Java多线程详解(内附源码)

线程是程序执行的最小单元,多线程是指程序同一时间可以有多个执行单元运行(这个与你的CPU核心有关). 在java中开启一个新线程非常简单,创建一个Thread对象,然后调用它的start方法,一个新线程就开启了. 那么执行代码放在那里呢?有两种方式:1. 创建Thread对象时,复写它的run方法,把执行代码放在run方法里.2. 创建Thread对象时,给它传递一个Runnable对象,把执行代码放在Runnable对象的run方法里. 如果多线程操作的是不同资源,线程之间不会相互影响,不会产

go语言创建新进程过程详解 (os.StartProcess源码分析)

关于如何使用go语言实现新进程的创建和进程间通信,我在网上找了不少的资料,但是始终未能发现让自己满意的答案,因此我打算自己来分析这部分源代码,然后善加利用,并且分享给大家,期望大家能从中获得启发. 首先我们来看一段代码 proc, _ := os.StartProcess(name, args, attr) if err != nil { fmt.Println(err) } _, err = proc.Wait() if err != nil { fmt.Println(err) } 我们来看

JavaScript中的跨域详解(内附源码)

什么是跨域? 什么是跨域? 所谓跨域,就是如果在不同的域名下面存在数据交互,这个时候就会存在跨域的问题,这里要说明的是在同一个网站不同的文件夹下的数据交互是不存在跨域问题的. 哪些情况下存在跨域问题? 主域和子域之间会存在跨域问题(比如 www.a.com 和 www.a.b.com). 不同的域名存在跨域问题,哪怕这两个域名指向的是同一个ip地址. 为什么 ajax 不可以跨域? 因为 ajax 是通过 XMLHttpRequest 这个对象来进行数据之间的交互的,而 XMLHttpReque

Java 正则表达式详解_正则表达式

body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI",Tahoma,Helvetica,Sans-Serif,"Microsoft YaHei", Georgia,Helvetica,Arial,sans-serif,宋体, PMingLiU,serif; font-size: 10.5pt; line-height: 1.5;}

H5EDU源码_微信平台源码001_吃包子

H5EDU源码_微信平台源码001_吃包子 H5edu.cn包含了上千款html5和微信开发的源码和几百门html5和微信开发的视频教程,是国内最专业的在线学习平台.网址:www.h5edu.cn 游戏描述:一款简单的休闲小游戏,每点击一次屏幕就会吃一个包子,看看自己在规定时间内能吃到多少包子吧!手速的测试,单身狗必玩! 游戏截图: 游戏下载地址:http://www.h5edu.cn/index.php?c=index&a=step&lessonid=791 游戏体验地址:http://

Cocos2d-x手机游戏开发与项目实践详解_随书代码

Cocos2d-x手机游戏开发与项目实战详解_随书代码 作者:沈大海  由于原作者共享的资源为UTF-8字符编码,下载后解压在win下显示乱码或还出现文件不全问题,现完整整理,解决所有乱码问题,供大家下载. 下载地址:http://download.csdn.net/detail/oyangyufu/7665049 Cocos2d-x手机游戏开发与项目实践详解_随书代码

Struts2配置详解_配置Action

Struts2的核心功能是action,对于开发人员来说,使用Struts2主要就是编写action,action类通常都要实现com.opensymphony.xwork2.Action接口,并实现该接口中的execute()方法. public String execute() throws Exception Struts2并不是要求所有编写的action类都要实现Action接口,也可以直接编写一个普通的Java类作为action,只要实现一个返回类型为String的无参的public方