Я новичок в библиотеке guava, и я довольно запутан с InputSupplier и OutputSupplier. Согласно javadoc, они являются просто фабриками для InputStream и OutputStream соответственно. Однако я не вижу ничего полезного из этих двух интерфейсов, может ли кто-нибудь показать мне пример, почему я должен использовать эти два API, кроме того, для более высокой абстракции?
Как использовать InputSupplier или OutputSupplier api для Guava?
Ответ 1
Основное преимущество обоих этих интерфейсов заключается в том, что они позволяют библиотечному коду управлять всем жизненным циклом фактических объектов ввода/вывода. Утилиты Guava никогда не закрывают 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));
Ответ 2
С помощью Guava InputSupplier/OutputSupplier вам не нужно обрабатывать различные IOExceptions, создаваемые при создании файлов FileInputStreams/FileOutputStreams. Guava автоматически обрабатывает эти исключения для вас, когда он вызывает методы InputSupplier.getInput()/OutputSupplier.getOutput() factory.
Инкапсулируя конструкцию ввода/вывода в этих интерфейсах factory, вы откладываете их создание и, таким образом, откладываете момент, когда вам нужно будет обрабатывать исключение IOException/FileNotFoundException, которое они могут выбросить. Фактически, вы откладываете это так много, что это Guava, который обрабатывает его для вас.
Затем вы можете заменить
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 может закрыть эти входы/выходы для вас, когда он контролирует весь их жизненный цикл (то есть, когда он использовал InputSupplier/OutputSupplier для их получения).