Limit the content available from a Java NIO Channel (File or Socket)

StackOverflow https://stackoverflow.com/questions/22103362

  •  18-10-2022
  •  | 
  •  

Вопрос

I'm pretty new to NIO and wanted to implement some feature with it, instead of typical Streams (which can do all sort of things).

What I'm not sure I can get is reading from a file into a buffer and limiting the content that I will transfer. Let's say from position 100 to 200 (even if file length is 1000). It also would be nice to do on network sockets.

I know that NIO keeps things basic to leverage OS capabilities that's why I'm not sure it can be done.

I was thinking that a tricky way to do it would be a 'LimitedReadChannel' that when it's should return less than the available buffer size it uses another byte-buffer and then transfer to the original one (1). But seems more tricky than necessary. I also don't want to use anything related to streams because it would defeat the purpose of using NIO.

(1) So far....

LimitedChannel.read(buffer) {
  if (buffer.available?? > contentLeft) {
    delegateChannel.read(smallerBuffer);
    // transfer from smallerBuffer to buffer
  } else {
    delegateChannel.read(buffer);
  }

}

Это было полезно?

Решение

I've found that Buffers admit to ask for the current limit or set a new one. So that wrapper channel (the one that limits the effective number of bytes read) could modify the buffer limit to avoid reading more...

Something like:

// LimitedChannel.java
// private int bytesLeft; // remaining amount of bytes to read
public int read(ByteBuffer buffer) {
  if (bytesLeft <= 0) {
    return -1;
  }
  int oldLimit = buffer.limit();
  if (bytesLeft < buffer.remaining()) {
    // ensure I'm not reading more than allowed
    buffer.limit(buffer.position() + bytesLeft);
  }
  int bytesRead = delegateChannel.read(buffer);
  bytesLeft -= bytesRead;
  buffer.limit(oldLimit);
  return bytesRead;
}

Anyway not sure if this already exists somewhere. It's difficult to find documentation about this use case...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top