Есть ли краткий способ создать InputSupplier для InputStream в Google Guava?

StackOverflow https://stackoverflow.com/questions/2363408

  •  23-09-2019
  •  | 
  •  

Вопрос

В Google Guava есть несколько фабричных методов для создания InputSuppliers, например.из byte[]:

ByteStreams.newInputStreamSupplier(bytes);

Или из File:

Files.newInputStreamSupplier(file);

Есть ли аналогичный способ создания InputSupplier для данного InputStream?

То есть более краткий способ, чем анонимный класс:

new InputSupplier<InputStream>() {
    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
видеть:источник

Другие советы

Невозможно преобразовать произвольный 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));

Это было бы так же неправильно, как обертывание Iterator в Iterable. Я считаю, что вероятность попадания такой вещи в библиотеку равна нулю.Как говорит Элу, вы можете использовать метод ByteStreams.copy(), но, похоже, нет очевидной причины использовать метод равенства() для двух потоков.

Я понимаю, что авторы гуавы не решаются добавить такой (тривиальный) метод - насколько часто он может полностью (или частично, но без знания того, где остался поток, так что после этого его практически невозможно использовать) читать два потока, просто чтобы посмотреть, есть ли они одинаковы, без какой-либо другой обработки данных?Поступают ли эти байты из неповторяемого источника чтения, например сетевого сокета?В противном случае, если это где-то просто файл или массив байтов в памяти, есть другие способы, которые позволяют провести проверку на равенство.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top