tags:

views:

141

answers:

1

Can I easily convert InputStream to BufferedReader using Guava?

I'm looking for something like:

InputStream inputStream = ...;
BufferedReader br = Streams.newBufferedReader(inputStream);

I can open files using the Files.newReader(File file, Charset charset). That's cool and I want to do the same using the InputStream.

UPDATE:

Using CharStreams.newReaderSupplier seems to verbose for me. Correct me if I'm wrong, but in order to easily convert InputStream to BufferedReader using Guava I have to do something like that:

final InputStream inputStream = new FileInputStream("/etc/fstab");
Reader bufferedReader = new BufferedReader(CharStreams.newReaderSupplier(new InputSupplier<InputStream>(){
      public InputStream getInput() throws IOException {
        return inputStream;
      }
    }, Charset.defaultCharset()).getInput());

Of course I can create helper do sth like:

return new BufferedReader(new InputStreamReader(inputStream));

However I think that such helper should be offered by Guava IO. I can do such trick for File instance. Why cannot I for InputStream?

// Guava can do this
Reader r = Files.newReader(new File("foo"), charset);
// but cannot do this
Reader r = SomeGuavaUtil.newReader(inputStream, charset);

Correct me If I'm wrong but it seems to me like lack in the API.

+3  A: 

No, there isn't anything quite like that in Guava. CharStreams is the general class for working with Readers and Writers and it has a method

InputSupplier<InputStreamReader> newReaderSupplier(
    InputSupplier<? extends InputStream> in, Charset charset)

which could be useful with any kind of supplier of InputStreams.

Obviously, you can just write new BufferedReader(new InputStreamReader(in, charset)) or wrap that in your own factory method as well.

Edit:

Yes, you wouldn't want to use the InputSupplier version when you already have an InputStream. It's sort of like how it's a bad idea to make an Iterable that can actually only work once, such as one that wraps an existing Iterator or Enumeration or some such. In general, using InputSupplier requires thinking about how you do I/O a little different, such as thinking of a File as something that can act as a supplier of FileInputStreams. I've used InputSuppliers that wrap whole requests to a server and return the response content as an InputStream, enabling me to use Guava utilities to copy that to a file, etc.

In any case, I'm not entirely sure why CharStreams doesn't have a method to create a Reader from an InputStream other than perhaps they didn't feel it was needed. You may want to file an issue requesting this.

ColinD
+1 - The obvious solution is for the OP to add a 3 line helper method to his application!
Stephen C
I won't create my helper method - that's why I'm using Guava :)Factory method newReaderSupplier is too verbose for me. I'll add explanation to the question above.
Henryk Konsek
Certainly it's nice when Guava already has utilities to do what you want to do, but I think when it doesn't it's a good idea to create your own utilities to do that and replace them later if Guava adds such functionality.
ColinD
Of course now I use my custom utilities when I need them. However I want to resign from them on the behalf of the Guava. I'll contact Google guys and ask them about helper method for converting InputStream to BufferedReader.
Henryk Konsek