InputStream源码分析

InputStream是一个抽象类,属于字节流的读取。

  1 /**
  2  * 该抽象类是所有字节输入流的超类。
  3  */
  4 public abstract class InputStream implements Closeable {
  5
  6     // 该变量用于确定在skip方法中使用的最大缓存数组大小。
  7     private static final int MAX_SKIP_BUFFER_SIZE = 2048;
  8
  9     /**
 10      * 从输入流中读取下一字节数据。返回的字节值为一个范围在0-255之间的int数。若由于到达流的尾部而没有字节可获取,则返回-1.
 11      * 直到数据可达,检测到流的末尾或者抛出一个异常,该方法才停止。
 12      *
 13      * @return     下一个字节,若到达输入流结尾,则返回-1.
 14      * @exception  IOException  if an I/O error occurs.
 15      */
 16     public abstract int read() throws IOException;
 17
 18     /**
 19      * 从输入流中读取一些字节并将它们存储到缓存数组b中。
 20      * 若b的长度为0,则没有字节被读取,返回0;若由于流在文件的尾部,没有字节可读,则返回-1。
 21      * 读取的第一个字节保存到b[0],下一个保存到b[1],以此类推。读取字节的数组小于等于数组b的长度。
 22      *
 23      * @param      b   缓存所读取的数据
 24      * @return     读取字节数到缓存的数目。由于到达流的结尾而不可读取数据时,返回-1.
 25      * @exception  IOException  若输入流已经关闭或者其他I/O错误发生所导致第一个字节不能被读取而抛出的异常。不考虑到达文件尾部的情况。
 26      * @exception  NullPointerException  b==null的情况
 27      * @see        java.io.InputStream#read(byte[], int, int)
 28      */
 29     public int read(byte b[]) throws IOException {
 30         return read(b, 0, b.length);
 31     }
 32
 33     /**
 34      * 从输入流读取len个字节数据,并保存到数组中。读取的数组最多为len。真正读取的字节数目将作为返回值返回。
 35      * 若len=0,则没有字节需要读取,返回为0;若字节不可达,则返回-1。
 36      * 读取到的第一个字节保存到b[off]中,下一个保存在b[off+1],以此类推。
 37      *
 38      * @param      b     缓存所读取的数据
 39      * @param      off   将读取的数据写入数组b的起始偏移地址
 40      * @param      len   读取的最大字节数组
 41      * @return     保存到buffer中真正的字节数,若由于到达流的结尾而无法读取数据,返回-1.
 42      * @exception  IOException If the first byte cannot be read for any reason
 43      * other than end of file, or if the input stream has been closed, or if
 44      * some other I/O error occurs.
 45      * @exception  NullPointerException b==null的情况.
 46      * @exception  IndexOutOfBoundsException 若off或len为负,或者len>b.length-off时,抛出该异常。
 47      * @see        java.io.InputStream#read()
 48      */
 49     public int read(byte b[], int off, int len) throws IOException {
 50         if (b == null) {
 51             throw new NullPointerException();
 52         } else if (off < 0 || len < 0 || len > b.length - off) {
 53             throw new IndexOutOfBoundsException();
 54         } else if (len == 0) {
 55             return 0;
 56         }
 57
 58         int c = read();
 59         if (c == -1) {
 60             return -1;
 61         }
 62         b[off] = (byte)c;
 63
 64         int i = 1;
 65         try {
 66             for (; i < len ; i++) {
 67                 c = read();
 68                 if (c == -1) {
 69                     break;
 70                 }
 71                 b[off + i] = (byte)c;
 72             }
 73         } catch (IOException ee) {
 74         }
 75         return i;
 76     }
 77
 78     /**
 79      * 跳过输入流的n个字节的数据,并返回真正跳过的字节数目。若n为负,则没有字节被跳过。
 80      * 方法skip会创建一个字节数组,不断读取字节到该数组中,直到n个字节被读取或到达输入流的结尾。
 81      *
 82      * @param      n   被跳过的字节数目.
 83      * @return     真正被跳过的字节数目.
 84      * @exception  IOException  if the stream does not support seek,
 85      *                          or if some other I/O error occurs.
 86      */
 87     public long skip(long n) throws IOException {
 88
 89         long remaining = n;
 90         int nr;
 91
 92         if (n <= 0) {
 93             return 0;
 94         }
 95
 96         int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);
 97         byte[] skipBuffer = new byte[size];
 98         while (remaining > 0) {
 99             nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
100             if (nr < 0) {
101                 break;
102             }
103             remaining -= nr;
104         }
105
106         return n - remaining;
107     }
108
109     /**
110      * 返回一个可以在该输入流中读取(或跳过)的字节数的估计,而不阻塞此输入流的下一次调用。
111      *
112      * @return     an estimate of the number of bytes that can be read (or skipped
113      *             over) from this input stream without blocking or {@code 0} when
114      *             it reaches the end of the input stream.
115      * @exception  IOException if an I/O error occurs.
116      */
117     public int available() throws IOException {
118         return 0;
119     }
120
121     /**
122      * 关闭输入流并释放与其相关的系统资源。
123      *
124      *
125      * @exception  IOException  if an I/O error occurs.
126      */
127     public void close() throws IOException {}
128
129     /**
130      * 标记输入流中当前的位置。当调用reset方法可以回到上次标记的位置,使得后面可以重新读取相同的字节。
131      * 参数readlimit告诉输入流允许被读取的字节数目。超过该数目,则标记位失效(invalid)
132      *
133      * @param   readlimit   在标志位变为invalid之前,可被读取的最大字节数目.
134      * @see     java.io.InputStream#reset()
135      */
136     public synchronized void mark(int readlimit) {}
137
138     /**
139      * 将流重定位到最后一次对此输入流调用mark方法时的位置。
140      * 当markSupported方法返回true,则
141      * 1、若mark方法自创建流以来从未被调用或者从流中读取的字节数目超过上次调用mark方法所定义的readlimit,则抛出IOException异常。
142      * 2、若未抛出IOException,则将该流重新设置为状态:最近一次调用mark后(若未调用过mark,则从文件开头开始)读取的所有字节重新提供
143      * 给read方法的后续调用者,如何从调用reset时起将作为下一输入数据的字节。
144      * 当markSupported方法返回false,则
145      * 1、调用reset方法会抛出IOException
146      * 2、若IOException未被抛出,则流将被重置到一个固定状态,该状态依赖于输入流的类型和被创建的方式。。。。
147      * The bytes that will be supplied to subsequent callers of the <code>read</code> method depend on the
148      * particular type of the input stream.
149      *
150      * @exception  IOException  若流未被标记或者标记失效。
151      * @see     java.io.InputStream#mark(int)
152      * @see     java.io.IOException
153      */
154     public synchronized void reset() throws IOException {
155         throw new IOException("mark/reset not supported");
156     }
157
158     /**
159      * 测试输入流是否支持test和reset方法。所支持的mark和reset是否是输入流实例的不变属性。
160      * InputStream的markSupported方法返回false。
161      *
162      * @return  若流实例支持mark和reset方法,返回true;否则返回false。
163      * @see     java.io.InputStream#mark(int)
164      * @see     java.io.InputStream#reset()
165      */
166     public boolean markSupported() {
167         return false;
168     }
169
170 }
时间: 2024-12-03 14:16:23

InputStream源码分析的相关文章

java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)

我们以ByteArrayInputStream,拉开对字节类型的“输入流”的学习序幕.本章,我们会先对ByteArrayInputStream进行介绍,然后深入了解一下它的源码,最后通过示例来掌握它的用法. 转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_02.html ByteArrayInputStream 介绍 ByteArrayInputStream 是字节数组输入流.它继承于InputStream.它包含一个内部缓冲区,该缓冲区包含从流

Hadoop之HDFS原理及文件上传下载源码分析(上)

HDFS原理 首先说明下,hadoop的各种搭建方式不再介绍,相信各位玩hadoop的同学随便都能搭出来. 楼主的环境: 操作系统:Ubuntu 15.10 hadoop版本:2.7.3 HA:否(随便搭了个伪分布式) 文件上传 下图描述了Client向HDFS上传一个200M大小的日志文件的大致过程: 首先,Client发起文件上传请求,即通过RPC与NameNode建立通讯. NameNode与各DataNode使用心跳机制来获取DataNode信息.NameNode收到Client请求后,

Mybatis源码分析之Cache二级缓存原理 (五)

一:Cache类的介绍 讲解缓存之前我们需要先了解一下Cache接口以及实现MyBatis定义了一个org.apache.ibatis.cache.Cache接口作为其Cache提供者的SPI(ServiceProvider Interface) ,所有的MyBatis内部的Cache缓存,都应该实现这一接口 Cache的实现类中,Cache有不同的功能,每个功能独立,互不影响,则对于不同的Cache功能,这里使用了装饰者模式实现. 看下cache的实现类,如下图: 1.FIFOCache:先进

[Android]Volley源码分析(四)

上篇中有提到NetworkDispatcher是通过mNetwork(Network类型)来进行网络访问的,现在来看一下关于Network是如何进行网络访问的. Network部分的类图: Network有一个实现类BasicNetwork,它有一个mHttpStack的属性,实际的网络请求是由这个mHttpStack来进行的,看BasicNetwork的performRequest()方法, 1 @Override 2 public NetworkResponse performRequest

mybatis源码分析(一)

mybatis源码分析(sqlSessionFactory生成过程) 1. mybatis框架在现在各个IT公司的使用不用多说,这几天看了mybatis的一些源码,赶紧做个笔记. 2. 看源码从一个demo引入如下: public class TestApp { private static SqlSessionFactory sqlSessionFactory; static { InputStream inputStream; String resource = "mybatis-confi

Okio源码分析

square在开源社区的贡献是卓越的,这里是square在Android领域贡献的开源项目. 1. okio概念 okio是一个由square公司开发的开源库,它弥补了Java.io和java.nio的不足,能够更方便快速的读取.存储和处理数据. okio有自己的流类型Source和Sink,对应于java.io的InputStream和OutputStream. okio内部引入了ByteString和Buffer,提升了效率和性能. okio引入了超时机制. okio规模不大,代码精巧,是源

MyBatis源码分析-MyBatis初始化流程

MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录.如何新建MyBatis源码工程请点击MyBatis源码分析-IDEA新建MyBatis源码工程. MyBatis初始化的过程也就是创建Configura

详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析] good

目录 前言 现象 源码分析 HandlerMethodArgumentResolver与HandlerMethodReturnValueHandler接口介绍 HandlerMethodArgumentResolver与HandlerMethodReturnValueHandler接口的具体应用 常用HandlerMethodArgumentResolver介绍 常用HandlerMethodReturnValueHandler介绍 本文开头现象解释以及解决方案 编写自定义的HandlerMet

Volley源码分析

Volley源码分析 Volley简介 volley官方地址 在Google I/0 2013中发布了Volley.Volley是Android平台上的网络通信库,能使网络通信更快,更简单,更健壮. 这是Volley名称的由来:a burst or emission of many things or a large amount at once.Volley特别适合数据量不大但是通信频繁的场景. Github上面已经有大神做了镜像,使用Gradle更方便.Volley On Github Vo