InputStream方法摘要:
public abstract int read() throws IOException;
public int read(byte b[]) throws IOException
public int read(byte b[], int off, int len) throws IOException
public long skip(long n) throws IOException
public int available() throws IOException
public void close() throws IOException
public synchronized void mark(int readlimit)
public boolean markSupported()
package java.io;
/**
* This abstract class is the superclass of all classes representing
* an input stream of bytes.
* 这个抽象类是所有字节输入流类的超类。
*/
public abstract class InputStream implements Closeable {
// 允许跳过的最大字节数
private static final int MAX_SKIP_BUFFER_SIZE = 2048;
/**
* 从输入流中读取下一个字节。返回0到255的整数,读到流的结尾返回-1.
* 为什么不直接返回读取的字节的byte类型?是为了防止读到全1的字节,11111111是-1与结束符-1冲突,
* 如果直接返回byte可能会导致流提前结束 <见FileInputStream>
*
* 该方法是唯一抽象方法,子类必须实现该方法
*
* @return 下一个数据字节,如果到达流末尾返回-1
* 下一个数据字节就是已经读取的这个字节,开始我理解成是下一个待读取的字节。
* @exception IOException if an I/O error occurs.
*/
public abstract int read() throws IOException;
/**
* 从输入流中读一些字节到缓冲数组中。返回实际读取的字节数。
*
* 如果数组b的长度是0,不会读取字节,结果返回0.读到流结束返回-1.
*
* 这个方法和read(b, 0, b.length)有同样的效果。
*
* @param b the buffer into which the data is read.
* @return 实际读取字节数,或-1
* @exception IOException
* @exception NullPointerException if <code>b</code> is <code>null</code>.
* @see java.io.InputStream#read(byte[], int, int)
*/
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
/**
* 就是简单的重复调用read()方法,
*
* @param b 缓冲数组
* @param off 要写入数据的数组开始位置 <code>b</code>
* @param len 要读取的最大字节数
* @return 读到缓冲数组中的实际字节数,到流结尾返回-1
* @exception IOException
* @exception NullPointerException If <code>b</code> is <code>null</code>.
* @exception IndexOutOfBoundsException off是复制,len是复制,或len大于b.length - off
* @see java.io.InputStream#read()
*/
public int read(byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
int c = read();
//空文件,直接返回-1,退出
if (c == -1) {
return -1;
}
//存储第一个字节
b[off] = (byte)c;
int i = 1;
try {
for (; i < len ; i++) {
c = read();
if (c == -1) {
break;
}
b[off + i] = (byte)c;
}
} catch (IOException ee) {
}
return i;
}
/**
* 从输入流中跳过或忽略n个字节
* 就是简单的重复调用read()方法,把n个字节保存在skipBuffer数组中,不返回给程序。
*
* @param n 跳过字节数
* @return 实际跳过的字节数
* @exception IOException if the stream does not support seek,
* or if some other I/O error occurs.
*/
public long skip(long n) throws IOException {
long remaining = n;
int nr;
if (n <= 0) {
return 0;
}
//当跳过的字节数大于MAX_SKIP_BUFFER_SIZE时,就跳过MAX_SKIP_BUFFER_SIZE字节数。
int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);
byte[] skipBuffer = new byte[size];
while (remaining > 0) {
nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
if (nr < 0) {
break;
}
remaining -= nr;
}
return n - remaining;
}
/**
* 返回估计可以读的字节数,怎么估计的??
* 只是个估计值,不应该用这个返回值去定义缓冲数组的大小
* 子类应该重写这个方法
*
* @return an estimate of the number of bytes that can be read (or skipped
* over) from this input stream without blocking or 0 when
* it reaches the end of the input stream.
* @exception IOException if an I/O error occurs.
*/
public int available() throws IOException {
return 0;
}
/**
* Closes this input stream and releases any system resources associated
* with the stream.
* 关闭输入流,释放所有占用的系统资源
* InputStream中没有具体实现
*
* @exception IOException if an I/O error occurs.
*/
public void close() throws IOException {}
/**
* 与reset()方法一起使用,可以实现重复利用InputStream中的指定一段数据
*
* @param readlimit the maximum limit of bytes that can be read before
* the mark position becomes invalid.
* @see java.io.InputStream#reset()
*/
public synchronized void mark(int readlimit) {}
public synchronized void reset() throws IOException {
throw new IOException("mark/reset not supported");
}
/**
* 测试输入流是否支持mark(),reset()功能,默认不支持
* @return true if this stream instance supports the mark
* and reset methods; <code>false</code> otherwise.
* @see java.io.InputStream#mark(int)
* @see java.io.InputStream#reset()
*/
public boolean markSupported() {
return false;
}
}
直接已知子类(链接至源码分析):
AudioInputStream,
ByteArrayInputStream
FileInputStream,
FilterInputStream,
ObjectInputStream,
PipedInputStream,
SequenceInputStream,
StringBufferInputStream