我试图编写扩展InputStream的输入流并学习以下内容
输入流是一个抽象类,它包含抽象方法和实现某些方法。注意到InputStream包含一个抽象方法
public abstract int read() throws IOException;
我不太清楚这种方法的作用。所以,引用了另一个扩展InputStream的输入流,得到FilterInputStream
扩展InputStream
,读取方法实现就像
public int read() throws IOException {
return in.read();
}
in
这里指的是基础输入流。考虑FilterInputStream
的构造函数,就像
protected FilterInputStream(InputStream in) {
this.in = in;
}
在read()方法实现中,这只是在其父类中调用read方法,该方法是InputStream
,它只是一个抽象方法。
我对这些感到困惑。请帮我了解一下。
答案 0 :(得分:2)
InputStream中的read()方法是什么?
它读取一个字节的数据。它必须由InputStream
的任何(非抽象)子类实现。
在FilterInputStream
案例中,它是通过从另一个流中读取来实现的;即过滤器正在包裹的流。该流将是InputStream
的某个子类的实例,它实现read()
以实际从某处读取数据。
当我调用FSDataInputStream的read方法时会发生什么?
您呼叫最终在read()
包裹的流上调用FSDataInputStream
;即在FSDataInputStream
构造函数中传递的那个。
我们在这里添加read()方法只是为了避免编译错误吗?或者我们还有其他用途吗?
read()
API中InputStream
方法的目的是成为实际流类中实际方法的占位符。
read()
中FilterInputStream
方法的目的是成为实际方法。它通过将read()
调用委托给链中的下一个流来完成此操作。 (请注意,通常,FilterInputStream
必须被子类化才有用,并且您希望子类至少覆盖一些read
方法。)
在这种情况下,FSDataInputStream
(FilterInputStream
)充当适配器,允许常规FSInputStream
用作DataInputStream
。对于read()
方法,简单委派就足够了。
答案 1 :(得分:0)
正如,@ JB Nizet建议ByteArrayInputStream
以清晰的方式实现读取,代码片段如下,
public synchronized int read() {
return (pos < count) ? (buf[pos++] & 0xff) : -1;
}
因此,这将返回缓冲区中的下一个字节,该字节被声明为
protected byte buf[];
其中buf []是由流的创建者提供的字节数组。缓冲区中的元素是唯一可以从流中读取的字节; element buf [pos]是要读取的下一个字节。
为什么它返回结果(buf [pos ++]&amp; 0xff)?
这是一个nice explanation,它让我们明白为什么value & with 0xff
已完成。
即;以有符号值返回结果(0到255之间)。这会将无符号值(字节)转换为带&
的{{1}}带符号值。