【问题标题】:Is there a concise way to create an InputSupplier for an InputStream in Google Guava?是否有一种简洁的方法可以在 Google Guava 中为 InputStream 创建 InputSupplier?
【发布时间】:2010-03-02 13:35:38
【问题描述】:

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

ByteStreams.newInputStreamSupplier(bytes);

或来自File

Files.newInputStreamSupplier(file);

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

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

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

背景:我想使用 InputStreams,例如Files.copy(...)ByteStreams.equal(...)

【问题讨论】:

    标签: java io guava


    【解决方案1】:

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

    正如 Dimitris 所建议的,InputSupplierInputStream 的关联方式与 IterableIterator 的关联方式相同。您描述的匿名类是不正确的,因为它每次调用getInput() 时都会返回相同 流,因此后续调用将返回一个已经耗尽并关闭的InputStream

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

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

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

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

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

    【讨论】:

    • 可以更新此答案以使其更加最新吗?截至发表此评论时,所有供应商类现已弃用。
    • 对不起@chakrit,但我不再使用番石榴,而且我不熟悉当前的隐喻。如果有人用新类编写了一个新版本,我很乐意为它投票!
    【解决方案2】:

    不,我什么都没看到。
    我认为您已经找到了最好的方法。
    将输入流存储在字节数组或文件中并使用 ByteStreams.newInputStreamSupplier 创建供应商的唯一替代方法() 或 Files.newInputStreamSupplier(),但我不鼓励这样做。
    你也可以使用

    public static long copy(InputStream from, OutputStream to)
    来自
    ByteStreams
    见:src

    【讨论】:

    • stackoverflow.com/a/19553971/9636 应该是正确的答案,因为它解释了为什么你不能这样做。
    • 你是对的,但三年后 jbyler 提出了一些解决方案;)
    • 这就是我链接到的解决方案。
    【解决方案3】:

    这就像将 Iterator 包装到 Iterable 一样错误,我觉得这样的东西进入库的可能性几乎为零。正如 elou 所说,您可以使用 ByteStreams.copy() 方法,但似乎没有明显的理由在两个流上执行 equals() 。

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

    【讨论】:

      猜你喜欢
      • 2014-05-25
      • 2011-12-29
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 2010-09-06
      • 2015-09-01
      • 2023-03-21
      相关资源
      最近更新 更多