Подтвердить что ты не робот

Как использовать InputSupplier или OutputSupplier api для Guava?

Я новичок в библиотеке guava, и я довольно запутан с InputSupplier и OutputSupplier. Согласно javadoc, они являются просто фабриками для InputStream и OutputStream соответственно. Однако я не вижу ничего полезного из этих двух интерфейсов, может ли кто-нибудь показать мне пример, почему я должен использовать эти два API, кроме того, для более высокой абстракции?

4b9b3361

Ответ 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 для их получения).