是否可以在 Java 中生成动态 InputStream?

Posted

技术标签:

【中文标题】是否可以在 Java 中生成动态 InputStream?【英文标题】:Is it possible to generate a dynamic InputStream in Java? 【发布时间】:2018-08-05 10:16:07 【问题描述】:

我在网上查看了 InputStreams,似乎您只能定义一个带有预定义输入的 InputStream,它将从中读取。如果我想要一个 InputStream,我们不确定数据是什么样子或它有多长,但它是在某处动态生成的,但完成后最终会返回零字节怎么办?

我所说的预定义是指大多数构造函数都接受您已经定义的要从中读取的内容(例如:ByteArrayInputStream(byte[] array), FileInputStream(File file))

我的用例是我有一个方法可以返回一定数量的数据(这个方法调用服务的时间未知,我想在动态生成这些数据时对其进行流式传输)

【问题讨论】:

将字节写入 PipedOutputStream 可能更容易,这些字节将从相应的 PipedOutputStream 中读取:***.com/a/23874232/1941359 【参考方案1】:

当然,只需扩展 InputStream 并让它为所欲为。 ByteArrayInputStream 正是这样做的。

【讨论】:

【参考方案2】:

InputStream 类是一个抽象类。它包含所有相关方法的定义,除了一个:

public int read() throws IOException

文档说:

从输入流中读取数据的下一个字节。值字节作为 int 返回,范围为 0 到 255。如果由于到达流的末尾而没有可用的字节,则返回值 -1。

因此,展示如何从“任意”数据源创建输入流的示例如下所示:

import java.io.IOException;
import java.io.InputStream;
import java.util.function.IntSupplier;

public class DynamicInputStreamExample

    public static void main(String[] args) throws IOException
    
        IntSupplier supplier = () -> methodThatProvidesTheData();
        InputStream inputStream = createStream(supplier);

        while (true)
        
            int read = inputStream.read();
            System.out.println("Read " + read + " from stream");
            if (read == -1)
            
                break;
            
        
    

    private static InputStream createStream(IntSupplier supplier)
    
        return new InputStream()
        
            @Override
            public int read() throws IOException
            
                return supplier.getAsInt();
            
        ;
    

    // Dummy implementation of a method that provides the data,
    // as a sequence of 6 bytes. It returns -1 if no more data
    // is available.
    private static final int data[] =  'H', 'e', 'l', 'l', 'o' ;
    private static int index = 0;
    private static int methodThatProvidesTheData()
    
        if (index >= data.length)
        
            return -1;
        
        return data[index++];
    



注意:根据数据的生成方式,额外覆盖InputStream 类的其他方法可能会有所帮助。特别是,read(byte[] b, int off, int len) method 从源中读取 array 字节。这样做的主要好处是,您可以在一次读取多个字节时获得(高得多)更高的性能。但是,当这与您无关时,只需覆盖 int read() 方法就足够了。

【讨论】:

以上是关于是否可以在 Java 中生成动态 InputStream?的主要内容,如果未能解决你的问题,请参考以下文章

如何在JSP网页中生成动态图表

是否有在Java中生成随机字符的功能?

在 java/scala 中生成 ecdsa 32 字节私钥

理解如何创建实体管理器或者我是不是可以在 JAVA EE 中生成它们的问题 [重复]

在eclipse中生成的java代码自动完成

如何在 Webpack 中生成动态导入块名称