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