是否有简洁的方法为Google Guava中的InputStream创建InputSupplier?

时间:2010-03-02 13:35:38

标签: java io guava

Google Guava中有一些工厂方法可用于创建InputSuppliers,例如来自byte[]

ByteStreams.newInputStreamSupplier(bytes);

或来自File

Files.newInputStreamSupplier(file);

是否有类似的方法为给定的InputSupplier创建InputStream

也就是说,这种方式比匿名类更简洁:

new InputSupplier<InputStream>() {
    public InputStream getInput() throws IOException {
        return inputStream;
    }
};

背景:我想将InputStream用于例如Files.copy(...)ByteStreams.equal(...)

3 个答案:

答案 0 :(得分:13)

无法将任意InputStream转换为InputSupplier<InputStream>,因为InputSupplier<InputStream>应该是一个可以每次创建新的InputStream的对象调用其getInput()方法。只有当底层字节源可供重用时,才可能这样做;因此采用byte[]File并返回InputSupplier<InputStream>的工厂方法。

正如迪米特里斯所说,InputSupplierInputStream的关联方式与IterableIterator相关。您描述的匿名类不正确,因为每次调用getInput()时它都会返回相同的流,因此后续调用将返回已经用尽并关闭的InputStream

以下是您的匿名课程的另一个问题:InputSupplier的部分动机是限制实际InputStream的可见性,以便可以自动关闭它。如果您在InputStream中包含外部可见的InputSupplier,然后将其传递给实用程序方法,则实用程序方法可能会关闭您的InputStream。您可能对此感到满意,但这不是Guava想要推广的干净使用模式。

当我发现自己想要做同样的事情时,我意识到我正在倒退。而不是这样做:

Files.copy(InputSupplier.of(inputStream), destinationFile);

(不存在),我应该这样做:

ByteStreams.copy(inputStream, Files.newOutputStreamSupplier(destinationFile));

答案 1 :(得分:10)

不,我还没有看到任何东西。
我认为你找到了最好的方法。
唯一的选择是将输入流存储在字节数组或文件中并使用ByteStreams创建供应商.newInputStreamSupplier()或Files.newInputStreamSupplier(),但我不鼓励这样做。
您也可以使用

public static long copy(InputStream from, OutputStream to)
中的

ByteStreams
见:src

答案 2 :(得分:2)

将Iterator包装到Iterable会有错误,我觉得这样的事情进入库的可能性为零。正如elou所说,你可以使用ByteStreams.copy()方法,但似乎没有明显的理由在两个流上做equals()。

我理解番石榴作者犹豫要添加这样一个(微不足道的)方法 - 完全(或部分地,但不知道流被留在哪里,所以它就像以后一样无法使用)是多么常见的读取两个流只是为了看看它们是否相同,没有任何其他数据处理?这些字节是否来自不可重复读取的源,如网络套接字?否则,如果它只是某个文件或内存中的字节数组,还有其他方法可以进行相等性测试。