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

发布于 2024-08-23 15:38:54 字数 603 浏览 7 评论 0 原文

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(... )

There are a few factory methods in Google Guava to create InputSuppliers, e.g. from a byte[]:

ByteStreams.newInputStreamSupplier(bytes);

Or from a File:

Files.newInputStreamSupplier(file);

Is there a similar way to to create an InputSupplier for a given InputStream?

That is, a way that's more concise than an anonymous class:

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

Background: I'd like to use InputStreams with e.g. Files.copy(...) or ByteStreams.equal(...).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

别忘他 2024-08-30 15:38:54

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

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

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

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

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

不存在),而应该这样做:

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

There's no way to convert an arbitrary InputStream into an InputSupplier<InputStream>, because an InputSupplier<InputStream> is supposed to be an object that can create a fresh, new InputStream every time its getInput() method is called. This is only possible when the underlying source of bytes is available for re-use; hence the factory methods that take a byte[] or File and return an InputSupplier<InputStream>.

As Dimitris suggests, InputSupplier relates to InputStream in the same way that Iterable relates to Iterator. The anonymous class you describe is incorrect because it returns the same stream every time getInput() is called, so subsequent invocations will return an InputStream that is already exhausted and closed.

Here is another problem with your anonymous class: part of the motivation for InputSupplier is to limit the visibility of the actual InputStream so that it can be closed automatically. If you wrap an externally-visible InputStream in an InputSupplier and then pass that into a utility method, the utility method may close your InputStream. You might be OK with that but that's not a clean usage pattern that Guava would want to promote.

When I found myself wanting to do the same thing, I realized I was doing it backwards. Instead of doing this:

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

(doesn't exist), I should instead be doing this:

ByteStreams.copy(inputStream, Files.newOutputStreamSupplier(destinationFile));
征﹌骨岁月お 2024-08-30 15:38:54

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

public static long copy(InputStream from, OutputStream to)

from

ByteStreams

see:src

No, I haven't seen anything.
I think you have found the best way.
The only alternative where to store the inputstream in a byte array or a file and create a Supplier with ByteStreams.newInputStreamSupplier() or Files.newInputStreamSupplier(), but I would discourage to do like that.

You could also use

public static long copy(InputStream from, OutputStream to)

from

ByteStreams

see:src

旧话新听 2024-08-30 15:38:54

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

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

That would be as wrong as wrapping an Iterator to an Iterable, I feel there is like zero probability of such a thing going into the library. As elou says, you can use ByteStreams.copy() method, but there doesn't seem to be an obvious reason to do equals() on two streams.

I understand guava authors hesitation to add such a (trivial) method - how common can it be to fully (or partially, but without knowing where the stream was left, so it's as good as unusable thereafter) read two streams just to see if they are the same, without any other processing of the data? Do these bytes come from a non-repeatable-read source, like a network socket? Otherwise, if it is just a file somewhere, or an in-memory byte array, there are other ways that lend themselves to do an equality test.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文