通过JDK源码学习InputStream详解
java开发全栈
一枚全栈开发大叔,每周分享python/java软件开发实战技术文章,分享编程前端后端开发测试技术,现在关注即可免费领取编程开发最新资料哦!
Official Account
--java.lang.Object--java.io.InputStream
类定义
public abstract class InputStream implements Closeable
InputStream 被定为 public 且 abstract 的类,实现了Closeable接口。
Closeable 接口表示 InputStream 可以被close,接口定义如下:
public interface Closeable extends AutoCloseable {public void close() throws IOException;}
主要属性
private static final int MAX_SKIP_BUFFER_SIZE = 2048;private static final int DEFAULT_BUFFER_SIZE = 8192;private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
public abstract int read() throws IOException;public int read(byte b[]) throws IOException {return read(b, 0, b.length);}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();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;}
public byte[] readAllBytes() throws IOException {byte[] buf = new byte[DEFAULT_BUFFER_SIZE];int capacity = buf.length;int nread = 0;int n;for (;;) {while ((n = read(buf, nread, capacity - nread)) > 0)nread += n;if (n < 0)break;if (capacity <= MAX_BUFFER_SIZE - capacity) {capacity = capacity << 1;} else {if (capacity == MAX_BUFFER_SIZE)throw new OutOfMemoryError("Required array size too large");capacity = MAX_BUFFER_SIZE;}buf = Arrays.copyOf(buf, capacity);}return (capacity == nread) ? buf : Arrays.copyOf(buf, nread);}
public int readNBytes(byte[] b, int off, int len) throws IOException {Objects.requireNonNull(b);if (off < 0 || len < 0 || len > b.length - off)throw new IndexOutOfBoundsException();int n = 0;while (n < len) {int count = read(b, off + n, len - n);if (count < 0)break;n += count;}return n;}
public int available() throws IOException {return 0;}
public long skip(long n) throws IOException {long remaining = n;int nr;if (n <= 0) {return 0;}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;}
close方法
此方法用于关闭输入流,并且释放相关资源 。
public void close() throws IOException {}
transferTo方法
从输入流中按顺序读取全部字节并且写入到指定的输出流中,返回值为转移的字节数。转移过程中可能会发生不确定次的阻塞,阻塞可能发生在 read 操作或 write 操作。
主要逻辑是用 while 循环不断调用 read 方法操作读取字节,然后调用输出流的 write 方法写入,直到读取返回-1,即达到结尾。最后返回转移的字节数。
public long transferTo(OutputStream out) throws IOException {Objects.requireNonNull(out, "out");long transferred = 0;byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];int read;while ((read = this.read(buffer, 0, DEFAULT_BUFFER_SIZE)) >= 0) {out.write(buffer, 0, read);transferred += read;}return transferred;}
markSupported方法
是否支持 mark 和 reset 操作,这里直接返回 false,子类根据实际重写该方法。
public boolean markSupported() {return false;}
mark方法
标记输入流当前位置,与之对应的是 reset 方法,通过他们之间的组合能实现重复读取操作。另外它会传入 readlimit 参数,它用于表示该输入流中在执行 mark 操作后最多可以读 readlimit 个字节后才使 mark 的位置失效。
可以看到 InputStream 的 mark 方法是什么都不做的,子类中再具体实现。
public synchronized void mark(int readlimit) {}
reset方法
与 mark 方法对应,它可以重置输入流的位置到上次被 mark 操作标识的位置。InputStream 的 reset 方法直接抛出一个 IOException,子类中根据实际情况实现。
public synchronized void reset() throws IOException {throw new IOException("mark/reset not supported");}
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对"java开发全栈"的支持。
