Only 44 hours left in the trailboss' kickstarter!

New rewards and stretch goals. CLICK HERE!



  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Reader -> InputStream conversion  RSS feed

 
Rob Spoor
Sheriff
Posts: 20893
81
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
InputStreamReader can convert an InputStream into a Reader, and OutputStreamWriter can convert an OutputStream into a Writer. But why are there no classes for converting the other way?

Suppose you want to compress the data read from a Reader using GZIP compression. Now there is the GZIPInputStream, but that can only take an InputStream, not a Reader. There is also not a default class like ReaderInputStream.

Now I've looked at the source of InputStreamReader but that uses sun.nio.cs.StreamDecoder to do all of the actual work. Since I don't want to use any of the Sun internal classes, I'm kinda stuck.

Anyone have an idea?
 
Brian Cole
Author
Ranch Hand
Posts: 932
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Rob Prime:
InputStreamReader can convert an InputStream into a Reader, and OutputStreamWriter can convert an OutputStream into a Writer. But why are there no classes for converting the other way?

Suppose you want to compress the data read from a Reader using GZIP compression. Now there is the GZIPInputStream, but that can only take an InputStream, not a Reader. There is also not a default class like ReaderInputStream.

Now I've looked at the source of InputStreamReader but that uses sun.nio.cs.StreamDecoder to do all of the actual work. Since I don't want to use any of the Sun internal classes, I'm kinda stuck.

Anyone have an idea?


Well, do you know how you want to convert the 16-bit chars returned by the reader into 8-bit bytes?

Deciding on that is the hard part, but you shouldn't have to use any sun internal classes. possibilities:

  • strip off the highest 8 bits: just cast from char to byte
  • convert each char to two bytes (you'll have to choose which endian)
  • use a specific Charset: use CharsetEncoder or String.getBytes()

  • Code is out there if you look. For example, this one seems to use String.getBytes(charsetName).

    For the GZIP situation you mention, it would be best to just read the data with an InputStream to begin with.
    [ November 13, 2007: Message edited by: Brian Cole ]
     
    Rob Spoor
    Sheriff
    Posts: 20893
    81
    Chrome Eclipse IDE Java Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Originally posted by Brian Cole:
    Well, do you know how you want to convert the 16-bit chars returned by the reader into 8-bit bytes?

    Deciding on that is the hard part, but you shouldn't have to use any sun internal classes. possibilities:

  • strip off the highest 8 bits: just cast from char to byte
  • convert each char to two bytes (you'll have to choose which endian)
  • use a specific Charset: use CharsetEncoder or String.getBytes()

  • Code is out there if you look. For example, this one seems to use String.getBytes(charsetName).
    Well that was why I posted this here, since this is not a simple issue; some characters can be represented using a single byte, while some others need two bytes. Therefore, options 1 and 2 are not good. As for CharsetEncoder, this is an abstract class without any known subclasses, and since I'm not that good at encoding I can't really write a subclass myself.

    I also though about using Strings, but didn't want to use that yet because it would require a lot of new String objects. I've checked the code of the ReaderInputStream on Koders.com and guess that's the way to go.

    For the GZIP situation you mention, it would be best to just read the data with an InputStream to begin with.
    Well if I could I certainly would have. The problem is, sometimes you can't use an InputStream because some other API only returns a Reader.

    I guess I'll base my code on the Koders.com example. Thanks for the link.
    [ November 14, 2007: Message edited by: Rob Prime ]
     
    Jim Yingst
    Wanderer
    Sheriff
    Posts: 18671
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I expect the easiest thing to do here would be to simply read from the Reader and write to a file or ByteArrayOutputStream, then when you're done, read from the file or array. You can use an OutputStreamWriter to control the encoding used. This may not work for you if the stream is very large - a byte array may take too much memory, and writing and reading from a file may be slower than you want. Also for some applications you may want to be able to start reading before all the content has gone through the stream. In that case, the Koders code (actually from Apache, it seems) looks like a decent bet, and there are other examples out there using the same name.

    [Rob]: As for CharsetEncoder, this is an abstract class without any known subclasses, and since I'm not that good at encoding I can't really write a subclass myself.

    Not necessary. Use

    With this, you can probably improve on getBytes() since you won't have to create as many objects.
     
    Rob Spoor
    Sheriff
    Posts: 20893
    81
    Chrome Eclipse IDE Java Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Originally posted by Jim Yingst:
    Not necessary. Use

    With this, you can probably improve on getBytes() since you won't have to create as many objects.

    Ah thanks, I always hate it when the creating methods are somewhere else

    I really need to press that "Use" link some more.
     
    Jim Yingst
    Wanderer
    Sheriff
    Posts: 18671
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Aha - I found my own old code for this. I don't know if this is the best way to do it, but I wanted to try using piped streams for once. Worth a shot at least. The exception handling should probably be replaced with logging, whatever you use. Rethrowing as an unchecked exception is no good if you're in a separate thread; it will just go to the uncaught handler and print a stack trace.

    [ November 14, 2007: Message edited by: Jim Yingst ]
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!