正在为以下人员编写javadoc:
/**
* ...Buffers the input stream so do not pass in a BufferedInputStream ...
*/
public static void meth(InputStream is) throws IOException {
BufferedInputStream bis = new BufferedInputStream(is,
INPUT_STREAM_BUFFER_SIZE);
// rest omitted
}
但是,将缓冲输入流传入真的有问题吗?所以这个:
InputStream is = new BufferedInputStream(new FileInputStream("C:/file"), SIZE);
meth(is);
会将is
缓冲到bis
中 - 或者 Java 会检测到is
已经缓冲并设置bis = is
?如果是,不同的缓冲区大小会有所不同吗?如果没有,为什么不呢?
注意:我说的是输入流,但实际上这个问题对输出流也有效
但是,将缓冲输入流传入真的有问题吗?
没有。 这样做可能会产生很小的开销,但与读取输入的总体成本相比,它可以忽略不计。
如果你看一下BufferedInputStream
的代码,(例如read1
方法(,你会看到块读取在缓冲流堆叠时是高效的。
[重新示例代码:] java 会检测到已经缓冲并设置
bis = is
吗?
不。
如果没有,为什么不呢?
因为Java(语言,编译器(通常不理解Java库类的语义。 在这种情况下,由于这种优化的好处可以忽略不计,因此我不值得实施。
当然,您可以自由编写meth
方法来显式执行此类操作...虽然我预测这不会有什么区别。
我不太明白为什么在 read1 中,只有在请求的长度小于 buf.length 时才"费心"复制到输入缓冲区(或者如果输入流中有标记的位置(
我假设您指的是这段代码(read1
(:
if (len >= getBufIfOpen().length && markpos < 0) {
return getInIfOpen().read(b, off, len);
}
第一部分是说,如果用户请求的缓冲区大小小于流配置的缓冲区大小,我们不希望使缓冲短路。 (否则,我们会遇到一个问题,即使用较小的请求长度进行read(byte[], int, int)
将是悲观的。
第二部分与标记/重置的实现方式有关。 BufferedInputStream
不是在基础流上使用标记/重置(可能支持也可能不支持(,而是使用缓冲区来实现它。 你所看到的是这个逻辑的一部分。 (您可以自己处理细节...阅读源代码中的注释。
如果缓冲流两次,那么它将使用更多的内存,并且比只缓冲一次时速度慢,但它仍然可以工作。
当然值得记录您的流执行缓冲,以便用户知道他们不需要自己这样做。
一般来说,最好劝阻而不是积极防止这种滥用。
答案是否定的,Java不会检测到双重缓冲。
由用户来避免此问题。BufferedInputStream
无法知道传入构造函数的InputStream
是否被缓冲。
下面是 BufferedInputStream
构造函数的源代码:
public BufferedInputStream(InputStream in, int size) {
super(in);
if (size <= 0) {
throw new IllegalArgumentException("Buffer size <= 0");
}
buf = new byte[size];
}
编辑
从评论中,双重缓冲流有问题吗?
简短的回答是肯定的。
缓冲的想法是提高速度,以便将数据假脱机到内存中并以块的形式写出(通常写到非常慢的IO(。如果双重缓冲,则会将数据假脱机到内存中,然后将该数据刷新回内存中的其他位置。这在速度方面肯定是有代价的......