History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: JRUBY-929
Type: New Feature New Feature
Status: Open Open
Priority: Major Major
Assignee: Unassigned
Reporter: Bill Dortch
Votes: 1
Watchers: 2
Operations

If you were logged in you would be able to see more operations.
JRuby

Java input/output streams from Ruby string's backing byte array

Created: 11/May/07 12:48 AM   Updated: 12/May/08 01:24 PM
Component/s: Java Integration
Affects Version/s: JRuby 1.1+
Fix Version/s: None

Time Tracking:
Not Specified


 Description  « Hide
It would be useful to be able to read/write Java input/output streams directly from the backing byte array of Ruby strings. This would avoid unnecessary array allocation/copying (one user reports transmitting byte arrays of several hundred K derived from Ruby strings).

This functionality could be implemented as methods on String, or in some kind of helper class. Here's what the direct approach might look like:

ostream = (some kind of java.io.OutputStream)
a_string.to_java_output_stream(ostream) #=> writes the backing bytes to ostream

istream = a_string.to_java_input_stream #=> (some kind of java.io.InputStream)
aJavaApp.readSomeBytes(istream) #=> app reads stream from backing bytes

This would be easy enough to implement, but some care would need to be taken to ensure the integrity of the data. In the second case, for example, the very easy solution would seem to be to wrap the bytes (from the string's ByteList) in a ByteArrayInputStream. But B-A-I-S exposes the underlying array as a protected field; if/when we decide how to enable protected field/method access, Ruby's lax enforcement of protected/private visibility could lead to problems. (But that's a topic for a different issue - see JRUBY-194.)

A related feature that might be useful is the ability to read in a Ruby string from a Java input stream:

istream = (some kind of java.io.InputStream)
a_string = String.from_java_input_stream(istream)

As I said, there are other ways this functionality could be exposed. But there does seem to be a need/desire for this, especially since we really can't directly expose the backing bytes of RubyString/ByteList.

I imagine this would probably all be post-1.0 functionality.

Thoughts?

-Bill



 All   Comments   Work Log   Change History      Sort Order: Ascending order - Click to sort in descending order
Charles Oliver Nutter - 22/May/07 10:46 AM
I like the idea, but this goes pretty far outside the bounds of Ruby features. So basically, it starts to look like we're forking and adding a lot of functionality to core classes that MRI doesn't support. I'd like to avoid that as much as possible.

Better to work on in the short term would be making it easy and performant to wrap a Java stream with a Ruby IO object. That's in greater need than a way to dump strings directly right now.


Charles Oliver Nutter - 23/Oct/07 02:53 PM
Had any more thoughts on this, Bill? It could be something loaded as an extension, providing direct IO stream read/write to JRuby users.

Hugh Winkler - 09/Dec/07 12:03 PM
Just chiming in to support the concept. I may have more concrete feedback after I implement some stream stuff this week.

Jennifer Ball - 15/Apr/08 11:01 PM
I guess this was never implemented? This is exactly what I need right now. I'm trying to stream an image using send_data, and my image is on a Java ByteArrayOutputStream. I should get a byte array when calling toByteArray on it, which should be compatible with Ruby String, right? In any case, the following code doesn't work. What is the workaround that the other user you mentioned did to get this to work?

def scaleImage
// Do some Java2D image manipulation into a buffered image, biFiltered and then:
begin
isWritten = javax.imageio.ImageIO.write(biFiltered, "jpeg", os)
rescue
$stderr.print "Couldn't write file"
end

if isWritten
send_data os.toByteArray, :type => "image/jpeg", :disposition => "inline", :filename => "scaledkids.jpg"
end
end


Charles Oliver Nutter - 12/May/08 01:24 PM
Jennifer Ball: There is String.from_java_bytes to allow you to turn a byte[] into a Ruby string...that may be the workaround you're looking for, yes?