如何使用番石榴的输入供应商或输出供应商api?
我是番石榴库的新手,我对输入供应商和输出供应商非常困惑。根据javadoc的说法,它们分别只是InputStream和OutputStream的工厂。但是,我没有看到这两个接口有什么非常有用的东西,任何人都可以向我展示一个例子,为什么除了更高的抽象之外,我应该使用这两个API?
我是番石榴库的新手,我对输入供应商和输出供应商非常困惑。根据javadoc的说法,它们分别只是InputStream和OutputStream的工厂。但是,我没有看到这两个接口有什么非常有用的东西,任何人都可以向我展示一个例子,为什么除了更高的抽象之外,我应该使用这两个API?
这两个接口的主要优点是它们允许库代码控制实际输入/输出对象的整个生命周期。番石榴的公用事业从不关闭你直接进入的,因为这可能不是你想要发生的事情。即使他们这样做了,您仍然需要/处理创建对象的错误。供应商是一种懒惰的回调,允许一次性创建,使用和关闭实际对象,而无需您进行大量丑陋/和错误处理。InputStream
OutputStream
try
finally
try
finally
例如,只需查看将一个文件复制到另一个文件所需的代码(使用Guava实用程序将实际复制和流关闭代码最小化):
File in = ...
File out = ...
FileInputStream inStream = new FileInputStream(in);
boolean threw = true;
try {
/*
* Note how two try/finally blocks are needed here, in case creating
* outStream fails.
*/
FileOutputStream outStream = new FileOutputStream(out);
try {
ByteStreams.copy(inStream, outStream);
threw = false;
} finally {
Closeables.close(outStream, threw);
}
} finally {
Closeables.close(inStream, threw);
}
然后查看代码(如果您改用供应商):
File in = ...
File out = ...
ByteStreams.copy(Files.newInputStreamSupplier(in),
Files.newOutputStreamSupplier(out));
使用Guava的InputSupplier / OutputSupplier,您不必自己处理实例化FileInputStreams / FileOutputStreams时抛出的各种IOExceptions。Guava 会在调用 InputSupplier.getInput() / OutputSupplier.getOutput() 工厂方法时自动为您处理这些异常。
通过将输入/输出结构封装在这些工厂接口中,您可以延迟它们的实例化,从而推迟需要处理它们可能引发的IOException / FileNotFoundException的时刻。事实上,你推迟了它,以至于是番石榴为你处理它。
然后,您可以替换
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
} catch (FileNotFoundException ex) {
throw new RuntimeException(ex);
}
doSomething(inputStream);
跟
InputSupplier<FileInputStream> inputStreamSupplier = Files.newInputStreamSupplier(file);
doSomething(inputStreamSupplier);
编辑:另请参阅ColinD的答案,关于Guava在控制其整个生命周期时(即,当它使用输入供应商/输出供应商来获取它们时)如何为您关闭这些输入/输出。