Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何表示空的InputStream_Java_Java Stream_Inputstream - Fatal编程技术网

Java 如何表示空的InputStream

Java 如何表示空的InputStream,java,java-stream,inputstream,Java,Java Stream,Inputstream,我正在减少InputStreams流,如下所示: InputStream total = input.collect( Collectors.reducing( empty, Item::getInputStream, (is1, is2) -> new SequenceInputStream(is1, is2))); 对于标识InputStream,我使用: InputStream empty = new ByteArrayIn

我正在减少
InputStreams
流,如下所示:

InputStream total = input.collect(
    Collectors.reducing(
        empty,
        Item::getInputStream, 
        (is1, is2) -> new SequenceInputStream(is1, is2)));
对于标识
InputStream
,我使用:

InputStream empty = new ByteArrayInputStream(new byte[0]);

这是可行的,但是有没有更好的方法来表示空的
InputStream

因为
InputStream
只有一个抽象方法

public abstract int read()抛出IOException

返回:
数据的下一个字节,或
-1
(如果到达流的末尾)

通过一个实例创建一个空流是很容易的。 像这样:

InputStream empty = new InputStream() {
    @Override
    public int read() {
        return -1;  // end of stream
    }
};

但不可否认,它比你的空
ByteArrayInputStream

更多的是代码,我会走另一条路

通过
(is1,is2)->新的SequenceInputStream(is1,is2)
减少大量的
InputStream
实例可能会创建一个深度不平衡的
SequenceInputStream
实例树,这可能会变得非常低效

线性数据结构更合适:

InputStream total = new SequenceInputStream(
    Collections.enumeration(input.map(Item::getInputStream).collect(Collectors.toList())));
这将创建单个
SequenceInputStream
来处理所有收集的输入流。由于这在本质上也处理空列表情况,因此不再需要特殊的空
InputStream
实现


但是当你看的时候,你会发现这个类并没有什么神奇之处,事实上,我们甚至可以通过不使用像
Vector
Enumeration
这样的古老类来做得更好:

public class StreamInputStream extends InputStream {
    final Spliterator<? extends InputStream> source;
    final Consumer<InputStream> c = is -> in = Objects.requireNonNull(is);
    InputStream in;

    public StreamInputStream(Stream<? extends InputStream> sourceStream) {
        (source = sourceStream.spliterator()).tryAdvance(c);
    }
    public StreamInputStream(InputStream first, InputStream second) {
        this(Stream.of(first, second));
    }
    public int available() throws IOException {
        return in == null? 0: in.available();
    }
    public int read() throws IOException {
        if(in == null) return -1;
        int b; do b = in.read(); while(b<0 && next());
        return b;
    }
    public int read(byte b[], int off, int len) throws IOException {
        if((off|len) < 0 || len > b.length - off) throw new IndexOutOfBoundsException();
        if(in == null) return -1; else if(len == 0) return 0;
        int n; do n = in.read(b, off, len); while(n<0 && next());
        return n;
    }
    public void close() throws IOException {
        closeCurrent();
    }
    private boolean next() throws IOException {
        closeCurrent();
        return source.tryAdvance(c);
    }
    private void closeCurrent() throws IOException {
        if(in != null) try { in.close(); } finally { in = null; }
    }
}

自Java 11以来,您可以使用静态方法:

返回不读取字节的新InputStream。返回的流最初是打开的。通过调用close()方法关闭流。对close()的后续调用无效


如果您的项目中有Apache
commons io

import org.apache.commons.io.IOUtils

IOUtils.toInputStream("")

以什么方式更好?使用空的
BAIS
,有什么不好?只是一个想法。。。您知道,您可以将输入流收集到一个列表中,然后只需执行
SequenceInputStream(Collections.enumeration(yourCollectedList))
?@Kayaman相当小,但会创建一个额外的空字节数组。我最感兴趣的是,如果我错过了集合中的某些内容。emptyList()。仅供参考,您可以用
SequenceInputStream::new
替换
new SequenceInputStream(is1,is2)
。这很聪明(至少对我来说),1+哦,我需要尝试一下。。。我们使用的是第一种方法(正如我在评论中所说的),这看起来更圆滑,但接近于确认。。。这将影响我们的代码基础(再次!)非常值得注意的是,
InputStream.nullInputStream()
不支持
标记
,而不是
newbytearrayinputstream(新字节[0])
import org.apache.commons.io.IOUtils

IOUtils.toInputStream("")