Skip to content

Conversation

@Sahil-Shadwal
Copy link
Contributor

bindings(java): Support options for stream operations

Which issue does this PR close?

Closes #7077

Rationale for this change

Currently, the createInputStream and createOutputStream methods in the Java binding do not support passing options (such as offset, length, content-type, etc.). This limitation prevents users from utilizing the full capabilities of OpenDAL when working with streams.

This PR adds support for passing ReadOptions and WriteOptions to these methods, enabling more flexible and performant stream operations.

What changes are included in this PR?

  • Added createInputStream(String path, ReadOptions options) to Operator.java.
  • Added createOutputStream(String path, WriteOptions options) to Operator.java.
  • Updated OperatorInputStream and OperatorOutputStream to accept and pass options to the native layer.
  • Updated internal Rust JNI bindings (operator_input_stream.rs and operator_output_stream.rs) to parse Java options and use reader_options/writer_options.
  • Added a make_reader_options helper in lib.rs.

Are there any user-facing changes?

Yes, new public API methods are added to Operator.java:

  • public OperatorInputStream createInputStream(String path, ReadOptions options)
  • public OperatorOutputStream createOutputStream(String path, WriteOptions options)

AI Usage Statement

This PR was implemented with the assistance of Gemini 3 pro

…eam operations and `Operator.read` method.
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. releases-note/feat The PR implements a new feature or has a title that begins with "feat" labels Dec 25, 2025
Copy link
Member

@tisonkun tisonkun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution! LGTM.

To make ReadOptions more useful for OperatorInputStream, we may convey more option fields here.

Comment on lines +77 to +85
try (final OperatorInputStream is = op.createInputStream(
path, ReadOptions.builder().offset(4L).length(5L).build())) {
final byte[] buffer = new byte[5];
final int read = is.read(buffer, 0, 5);
assertThat(read).isEqualTo(5);
assertThat(new String(buffer)).isEqualTo("45678");
} catch (Exception e) {
throw new RuntimeException(e);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. What if we read once more?

That is, while I generally understand supporting ReadOptions to the input stream, I'm not quite sure what OpenDAL's reader should do if a range is specified - will it ends as finished? cc @Xuanwo

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is, while I generally understand supporting ReadOptions to the input stream, I'm not quite sure what OpenDAL's reader should do if a range is specified - will it ends as finished?

Yes, Reader is just read the input range and end with finished.

@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Dec 25, 2025
@tisonkun tisonkun merged commit a76040c into apache:main Dec 25, 2025
68 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm This PR has been approved by a maintainer releases-note/feat The PR implements a new feature or has a title that begins with "feat" size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

new feature: Binding Java's createInputStream and createOutputStream should supoort options

3 participants