Как получить Inputstream из Java 8 Streams? - PullRequest
0 голосов
/ 16 апреля 2019

У меня есть некоторые данные, передаваемые из разных файлов. В следующем формате:

Stream<String> linesModifiedAndAppendedFromVariousFiles=getLines();

Однако мне нужно передать это в метод библиотеки, который принимает InputStream или Reader в качестве параметра.

Как я могу передать этот поток Java 8 в InputStream или тип Reader?

P.S .: это не обертывание java.util.streams.Stream вокруг InputStream. То, что я ищу, это наоборот.

Ответы [ 2 ]

2 голосов
/ 16 апреля 2019

Вы можете сделать это с PipedReader и PipedWriter .

PipedReader reader = new PipedReader();

Runnable feeder = new Runnable() {
    @Override
    public void run() {
        try (PipedWriter writer = new PipedWriter(reader)) {
            linesModifiedAndAppendedFromVariousFiles.forEachOrdered(line -> {
                try {
                    writer.write(line);
                    writer.write('\n');
                } catch (IOException e) {
                    throw new UncheckedIOException(e);
                }
            });
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
};
new Thread(feeder).start();

someLibraryMethod.consumeReader(reader);
1 голос
/ 16 апреля 2019

A java.util.Stream концептуально представляет собой потенциально бесконечную, нереверсивную (как, например, когда вы проходите мимо записи, вы не можете вернуться к ней) последовательность, которая потенциально может позволить вам обрабатывать ее параллельно. Важно отметить, что «штуковины» в последовательности могут быть НИЧЕГО вообще. Например, вы можете иметь поток объектов Color.

A java.io.InputStream концептуально является потенциально бесконечной, необратимой, непараллелизуемой последовательностью байтов.

Эти две вещи просто не одинаковы.

Тем не менее, если у вас есть поток байтов, вы можете превратить его во входной поток. Вы просто решаете не использовать опцию параллелизации, присущую Stream, и затем эти две вещи начинают сводиться к одному и тому же. Однако, если у вас есть поток чего-то, что не является байтом, вам придется придумать «отображение».

Допустим, у вас есть поток строковых объектов. Допустим, это поток первых 4 чисел на английском языке (так: Arrays.asList("one", "two", "three", "four").stream()).

Как вы хотите отобразить этот поток строк в поток байтов? Одной из стратегий может быть рендеринг строк в байты с использованием кодировки UTF-8 и использование 0 символов в качестве разделителя. Другими словами, вы хотите получить тот же результат, что и этот гипотетический: new ByteArrayInputStream(new String("one\0two\0three\0four").getBytes(StandardCharsets.UTF_8)).

Можно представить себе функцию, которая принимает Stream<Byte> и превращает его в InputStream. Тем не менее, Stream<Byte> будет очень неэффективной концепцией. Можно также представить функцию, которая принимает Stream<T> вместе с функцией отображения, отображающей T в byte[], и константу-разделитель (или функцию, которая генерирует значение), которая создает разделители. Для приведенного выше примера, что-то вроде:

toInputStream(oneTwoThreeFour, str -> str.getBytes(StandardCharsets.UTF_8), "\0");

Насколько я знаю, этого нет ни в основных библиотеках, ни в таких местах, как гуава. Но написание должно быть достаточно тривиальным. Может быть, полстраницы кода.

...