Wrapping a ByteBuffer with an InputStream

后端 未结 6 1456
青春惊慌失措
青春惊慌失措 2020-12-01 04:46

I have a method that takes an InputStream and reads data from it. I would like to use this method with a ByteBuffer also. Is there a way to wrap a ByteBuffer so it can be ac

6条回答
  •  遥遥无期
    2020-12-01 05:34

    This is my version of InputStream & OutputStream implementation:

    ByteBufferBackedInputStream:

    public class ByteBufferBackedInputStream extends InputStream
    {
      private ByteBuffer backendBuffer;
    
      public ByteBufferBackedInputStream(ByteBuffer backendBuffer) {
          Objects.requireNonNull(backendBuffer, "Given backend buffer can not be null!");
          this.backendBuffer = backendBuffer;
      }
    
      public void close() throws IOException {
          this.backendBuffer = null;
      }
    
      private void ensureStreamAvailable() throws IOException {
          if (this.backendBuffer == null) {
              throw new IOException("read on a closed InputStream!");
          }
      }
    
      @Override
      public int read() throws IOException {
          this.ensureStreamAvailable();
          return this.backendBuffer.hasRemaining() ? this.backendBuffer.get() & 0xFF : -1;
      }
    
      @Override
      public int read(@Nonnull byte[] buffer) throws IOException {
          return this.read(buffer, 0, buffer.length);
      }
    
      @Override
      public int read(@Nonnull byte[] buffer, int offset, int length) throws IOException {
          this.ensureStreamAvailable();
          Objects.requireNonNull(buffer, "Given buffer can not be null!");
          if (offset >= 0 && length >= 0 && length <= buffer.length - offset) {
              if (length == 0) {
                  return 0;
              }
              else {
                  int remainingSize = Math.min(this.backendBuffer.remaining(), length);
                  if (remainingSize == 0) {
                      return -1;
                  }
                  else {
                      this.backendBuffer.get(buffer, offset, remainingSize);
                      return remainingSize;
                  }
              }
          }
          else {
              throw new IndexOutOfBoundsException();
          }
      }
    
      public long skip(long n) throws IOException {
          this.ensureStreamAvailable();
          if (n <= 0L) {
              return 0L;
          }
          int length = (int) n;
          int remainingSize = Math.min(this.backendBuffer.remaining(), length);
          this.backendBuffer.position(this.backendBuffer.position() + remainingSize);
          return (long) length;
      }
    
      public int available() throws IOException {
          this.ensureStreamAvailable();
          return this.backendBuffer.remaining();
      }
    
      public synchronized void mark(int var1) {
      }
    
      public synchronized void reset() throws IOException {
          throw new IOException("mark/reset not supported");
      }
    
      public boolean markSupported() {
          return false;
      }
    }
    

    ByteBufferBackedOutputStream:

    public class ByteBufferBackedOutputStream extends OutputStream
    {
        private ByteBuffer backendBuffer;
    
        public ByteBufferBackedOutputStream(ByteBuffer backendBuffer) {
            Objects.requireNonNull(backendBuffer, "Given backend buffer can not be null!");
            this.backendBuffer = backendBuffer;
        }
    
        public void close() throws IOException {
            this.backendBuffer = null;
        }
    
        private void ensureStreamAvailable() throws IOException {
            if (this.backendBuffer == null) {
                throw new IOException("write on a closed OutputStream");
            }
        }
    
        @Override
        public void write(int b) throws IOException {
            this.ensureStreamAvailable();
            backendBuffer.put((byte) b);
        }
    
        @Override
        public void write(@Nonnull byte[] bytes) throws IOException {
            this.write(bytes, 0, bytes.length);
        }
    
        @Override
        public void write(@Nonnull byte[] bytes, int off, int len) throws IOException {
            this.ensureStreamAvailable();
            Objects.requireNonNull(bytes, "Given buffer can not be null!");
            if ((off < 0) || (off > bytes.length) || (len < 0) ||
                ((off + len) > bytes.length) || ((off + len) < 0))
            {
                throw new IndexOutOfBoundsException();
            }
            else if (len == 0) {
                return;
            }
    
            backendBuffer.put(bytes, off, len);
        }
    }
    

提交回复
热议问题