Robert Jack Will
Robert Jack Will

Reputation: 11591

converting a java.util.stream.Stream<String> into a java.io.Reader

Part of my application is given an InputStream and wants to do some processing on this to produce another InputStream.

try (
  final BufferedReader inputReader = new BufferedReader(new InputStreamReader(inputStream, UTF_8), BUFFER_SIZE);
  final Stream<String> resultLineStream = inputReader.lines().map(lineProcessor::processLine);
  final InputStream resultStream = new ReaderInputStream(new StringStreamReader(resultLineStream), UTF_8);
) {
  s3Client.putObject(targetBucket, s3File, resultStream, new ObjectMetadata());
} catch (IOException e) {
  throw new RuntimeException("Exception", e);
}

I am using the new Java 8 BufferedReader.lines() to a Stream onto which I can easily map my processing function.

The only thing still lacking is class StringStreamReader() which is supposed to turn my Stream into a Reader from which Apache commons-io:ReaderInputStream can create an InputStream again. (The detour to readers and back seems reasonable to deal with encodings and line breaks.)

To be very clear, the code above assumes

public class StringStreamReader extends Reader {
  public StringStreamReader(Stream<String> stringStream) { ... }

  @Overwrite
  public int read(char cbuf[], int off, int len) throws IOException { ... }

  // possibly overwrite other methods to avoid bad performance or high resource-consumption
}

So is there any library that offers such a StringStreamReader class? Or this there another way to write the application code above without implementing a custom Reader or InputStream subclass?

Upvotes: 4

Views: 1318

Answers (1)

k5_
k5_

Reputation: 5568

You can do something like that:

    PipedWriter writer = new PipedWriter();
    PipedReader reader = new PipedReader();
    reader.connect(writer);

    strings.stream().forEach(string -> {
        try {
            writer.write(string);
            writer.write("\n");
        } catch (Exception e) {
            e.printStackTrace();
        }
    });

But i guess you want some form of lazy processing. Stream api does not really help in that case, you need a dedicated Thread + some buffer to do that.

Upvotes: 3

Related Questions