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

Fab*_*eeg 17 java io guava

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

ByteStreams.newInputStreamSupplier(bytes);
Run Code Online (Sandbox Code Playgroud)

或者来自File:

Files.newInputStreamSupplier(file);
Run Code Online (Sandbox Code Playgroud)

有没有类似的方法来创建InputSupplier给定的InputStream

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

new InputSupplier<InputStream>() {
    public InputStream getInput() throws IOException {
        return inputStream;
    }
};
Run Code Online (Sandbox Code Playgroud)

背景:我想将InputStreams与eg Files.copy(...)或者一起使用ByteStreams.equal(...).

jby*_*ler 13

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

正如迪米特里斯所暗示的那样,InputSupplier与涉及InputStream的方式Iterable有关Iterator.您描述的匿名类是不正确的,因为它每次调用时都返回相同的getInput(),因此后续调用将返回InputStream已经用尽和关闭的流.

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

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

Files.copy(InputSupplier.of(inputStream), destinationFile);
Run Code Online (Sandbox Code Playgroud)

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

ByteStreams.copy(inputStream, Files.newOutputStreamSupplier(destinationFile));
Run Code Online (Sandbox Code Playgroud)


elo*_*lou 10

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

public static long copy(InputStream from, OutputStream to)
Run Code Online (Sandbox Code Playgroud)
ByteStreams
Run Code Online (Sandbox Code Playgroud) 见:src

  • http://stackoverflow.com/a/19553971/9636应该是正确的答案,因为它解释了为什么你不能这样做. (3认同)