有没有简洁的方法为Google Guava中的InputStream创建InputSupplier?
Google Guava中有一些工厂方法可以创建InputSuppliers,例如从byte[]
:
ByteStreams.newInputStreamSupplier(bytes);
或者来自File
:
Files.newInputStreamSupplier(file);
是否有类似的方法为给定的InputStream
创建InputSupplier
?
也就是说,这种方式比匿名类更简洁:
new InputSupplier() { public InputStream getInput() throws IOException { return inputStream; } };
背景:我想将InputStreams与例如Files.copy(...)
或ByteStreams.equal(...)
。
不,我什么都没看到。
我想你找到了最好的方法。
将输入流存储在字节数组或文件中并使用ByteStreams.newInputStreamSupplier()或Files.newInputStreamSupplier()创建供应商的唯一选择,但我不鼓励这样做。
你也可以使用
public static long copy(InputStream from, OutputStream to)
从
ByteStreams
见: src
没有办法将任意InputStream
转换为InputSupplier
,因为InputSupplier
应该是一个对象,每次调用其getInput()
方法时都可以创建一个全新的InputStream
。 只有当底层字节源可供重用时,才有可能; 因此采用byte[]
或File
并返回InputSupplier
的工厂方法。
正如Dimitris所说, InputSupplier
与Iterable
与Iterator
相关的方式与InputStream
相关。 您描述的匿名类是不正确的,因为每次调用getInput()
时它都会返回相同的流,因此后续调用将返回已经用尽和关闭的InputStream
。
这是您的匿名类的另一个问题: InputSupplier
部分动机是限制实际InputStream
的可见性,以便它可以自动关闭。 如果在InputSupplier
包装外部可见的InputStream
,然后将其传递给实用程序方法,则实用程序方法可能会关闭InputStream
。 您可能对此感到满意,但这不是Guava想要推广的干净使用模式。
当我发现自己想要做同样的事情时,我意识到我正在倒退。 而不是这样做:
Files.copy(InputSupplier.of(inputStream), destinationFile);
(不存在),我应该这样做:
ByteStreams.copy(inputStream, Files.newOutputStreamSupplier(destinationFile));
这就像将Iterator包装到Iterable一样错误,我觉得这样的东西进入库的可能性为零。 正如elou所说,你可以使用ByteStreams.copy()方法,但似乎没有明显的理由在两个流上做equals()。
我理解番石榴作者犹豫要添加这样一个(微不足道的)方法 – 完全(或部分地,但不知道流被留在哪里,所以它就像以后无法使用一样好)是多么常见的阅读两个流只是为了看看他们是否是否相同,没有任何其他数据处理? 这些字节是否来自不可重复读取的源,如网络套接字? 否则,如果它只是某个文件或内存中的字节数组,还有其他方法可以进行相等性测试。