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

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

В Google Гуаве существует несколько методов factory для создания 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(...).

4b9b3361

Ответ 1

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

public static long copy(InputStream from, OutputStream to)
из
ByteStreams
см. src

Ответ 2

Невозможно преобразовать произвольный InputStream в InputSupplier<InputStream>, потому что InputSupplier<InputStream> должен быть объектом, который может создавать новый, новый InputStream каждый раз при вызове метода getInput(). Это возможно только тогда, когда базовый источник байтов доступен для повторного использования; следовательно, методы factory, которые принимают byte[] или File и возвращают InputSupplier<InputStream>.

Как предполагает Димитрис, InputSupplier относится к InputStream таким же образом, что Iterable относится к Iterator. Анонимный класс, который вы описываете, неверен, поскольку он возвращает тот же поток каждый раз, когда вызывается getInput(), поэтому последующие вызовы возвращают InputStream, который уже исчерпан и закрыт.

Вот еще одна проблема с вашим анонимным классом: часть мотивации для InputSupplier заключается в том, чтобы ограничить видимость фактического InputStream, чтобы он мог быть автоматически закрыт. Если вы завершите внешний вид InputStream в InputSupplier, а затем передайте его в метод утилиты, метод утилиты может закрыть ваш InputStream. Вы можете быть в порядке с этим, но это не чистый шаблон использования, который Гуава хотел бы продвигать.

Когда я обнаружил, что хочу сделать то же самое, я понял, что делаю это в обратном направлении. Вместо этого:

Files.copy(InputSupplier.of(inputStream), destinationFile);

(не существует), я должен сделать это:

ByteStreams.copy(inputStream, Files.newOutputStreamSupplier(destinationFile));

Ответ 3

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

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