Skip to content

Examples#

Reading Data#

Read from file#

Also see: Write to file

void read(Path file) throws IOException {
  var channel = FileChannel.open(file); //(1)
  try (var reader = MessageReader.of(channel)) {
    var string = reader.readString();
    var number = reader.readInt();
  }
}
  1. java.nio.channels.FileChannel is the most efficient way to read a file.
fun read(file: Path) {
  val channel = FileChannel.open(file) //(1)
  MessageReaders.of(channel).use { reader ->
    val string = reader.readString()
    val number = reader.readInt()
  }
}
  1. java.nio.channels.FileChannel is the most efficient way to read a file.

Read from channel#

Also see: Write to channel

void read(ReadableByteChannel channel) throws IOException {
  try (var reader = MessageReader.of(channel)) {
    var string = reader.readString();
    var number = reader.readInt();
  }
}
fun read(channel: ReadableByteChannel) {
  MessageReaders.of(channel).use { reader ->
    val string = reader.readString()
    val number = reader.readInt()
  }
}

Read from stream#

Also see: Write to stream

void read(InputStream stream) throws IOException {
  try (var reader = MessageReader.of(stream)) {
    var string = reader.readString();
    var number = reader.readInt();
  }
}
fun read(stream: InputStream) {
  MessageReaders.of(stream).use { reader ->
    val string = reader.readString()
    val number = reader.readInt()
  }
}

Read from buffer#

Also see: Write to buffer

void read(LeasedByteBuffer buffer) throws IOException {
  try (var reader = MessageReader.of(buffer)) {
    var string = reader.readString();
    var number = reader.readInt();
  }
}
fun read(buffer: LeasedByteBuffer) {
  MessageReaders.of(buffer).use { reader ->
    val string = reader.readString()
    val number = reader.readInt()
  }
}

Read array#

Also see: Write array

List<String> read(MessageReader reader) throws IOException {
  var size = reader.readArrayHeader();
  var list = new ArrayList<String>(size);
  for (int i = 0; i < size; i++) {
    var element = reader.readString();
    list.add(element);
  }
  return list;
}
fun read(reader: MessageReader): List<String> {
  val size = reader.readArrayHeader()
  return buildList(size) {
    repeat(size) {
      val element = reader.readString()
      add(element)
    }
  }
}

Read map#

Also see: Write map

Map<String, Integer> read(MessageReader reader) throws IOException {
  var size = reader.readMapHeader();
  // JDK 19+: var map = HashMap.<String, Integer>newHashMap(size);
  var map = new HashMap<String, Integer>();
  for (int i = 0; i < size; i++) {
    var key = reader.readString();
    var value = reader.readInt();
    map.put(key, value);
  }
  return map;
}
fun read(reader: MessageReader): Map<String, Int> {
  val size = reader.readMapHeader()
  return buildMap(size) {
    repeat(size) {
      val key = reader.readString()
      val value = reader.readInt()
      put(key, value)
    }
  }
}

Set reader options#

Also see: Set writer options

void read(ReadableByteChannel channel) throws IOException {
  try (var reader = MessageReader.of(channel, options -> options
      .allocator(BufferAllocator.ofUnpooled()) //(1)
      .readBufferCapacity(1024 * 8)
      .stringDecoder(MessageDecoder.ofStrings())
      .identifierDecoder(MessageDecoder.ofStrings()))
  ) { /* read some values */ }
}
  1. Sets reader options by calling OptionBuilder methods. All options are optional; this example shows their defaults.
fun read(channel: ReadableByteChannel) {
  MessageReaders.of(
    channel,
    allocator = BufferAllocators.ofUnpooled(), //(1)
    readBufferCapacity = 1024 * 8,
    stringDecoder = MessageDecoders.ofStrings(),
    identifierDecoder = MessageDecoders.ofStrings(),
  ).use { /* read some values */ }
}
  1. Sets reader options by setting named method parameters. All options are optional; this example shows their defaults.

Writing Data#

Write to file#

Also see: Read from file

void write(Path file) throws IOException {
  var channel = FileChannel.open(file, WRITE, CREATE); //(1)
  try (var writer = MessageWriter.of(channel)) {
    writer.write("Hello, MxPack!");
    writer.write(42);
  }
}
  1. java.nio.channels.FileChannel is the most efficient way to write a file.
fun write(file: Path) {
  val channel = FileChannel.open(file, WRITE, CREATE) //(1)
  MessageWriters.of(channel).use { writer ->
    writer.write("Hello, MxPack!")
    writer.write(42)
  }
}
  1. java.nio.channels.FileChannel is the most efficient way to write a file.

Write to channel#

Also see: Read from channel

void write(WritableByteChannel channel) throws IOException {
  try (var writer = MessageWriter.of(channel)) {
    writer.write("Hello, MxPack!");
    writer.write(42);
  }
}
fun write(channel: WritableByteChannel) {
  MessageWriters.of(channel).use { writer ->
    writer.write("Hello, MxPack!")
    writer.write(42)
  }
}

Write to stream#

Also see: Read from stream

void write(OutputStream stream) throws IOException {
  try (var writer = MessageWriter.of(stream)) {
    writer.write("Hello, MxPack!");
    writer.write(42);
  }
}
fun write(stream: OutputStream) {
  MessageWriters.of(stream).use { writer ->
    writer.write("Hello, MxPack!")
    writer.write(42)
  }
}

Write to buffer#

Also see: Read from buffer

LeasedByteBuffer write() throws IOException {
  var output = MessageOutput.ofBuffer();
  try (var writer = MessageWriter.of(output)) {
    writer.write("Hello, MxPack!");
    writer.write(42);
  }
  return output.get();
}
fun write(): LeasedByteBuffer {
  val output = MessageOutputs.ofBuffer()
  MessageWriters.of(output).use { writer ->
    writer.write("Hello, MxPack!")
    writer.write(42)
  }
  return output.get()
}

Write array#

Also see: Read array

void write(MessageWriter writer, List<String> list) throws IOException {
  writer.writeArrayHeader(list.size());
  for (var element : list) {
    writer.write(element);
  }
}
fun write(writer: MessageWriter, list: List<String>) {
  writer.writeArrayHeader(list.size)
  for (element in list) {
    writer.write(element)
  }
}

Write map#

Also see: Read map

void write(MessageWriter writer, Map<String, Integer> map) throws IOException {
  writer.writeMapHeader(map.size());
  for (var entry : map.entrySet()) {
    writer.write(entry.getKey());
    writer.write(entry.getValue());
  }
}
fun write(writer: MessageWriter, map: Map<String, Int>) {
  writer.writeMapHeader(map.size)
  for ((key, value) in map) {
    writer.write(key)
    writer.write(value)
  }
}

Set writer options#

Also see: Set reader options

void write(WritableByteChannel channel) throws IOException {
  try (var writer = MessageWriter.of(channel, options -> options
      .allocator(BufferAllocator.ofUnpooled()) //(1)
      .writeBufferCapacity(1024 * 8)
      .stringEncoder(MessageEncoder.ofStrings())
      .identifierEncoder(MessageEncoder.ofStrings()))
  ) { /* write some values */ }
}
  1. Sets writer options by calling OptionBuilder methods. All options are optional; this example shows their defaults.
fun write(channel: WritableByteChannel) {
  MessageWriters.of(
    channel,
    allocator = BufferAllocators.ofUnpooled(), //(1)
    writeBufferCapacity = 1024 * 8,
    stringEncoder = MessageEncoders.ofStrings(),
    identifierEncoder = MessageEncoders.ofStrings()
  ).use { /* write some values */ }
}
  1. Sets writer options by settings named method parameters. All options are optional; this example shows their defaults.

Buffer Allocation#

Use default allocator#

void read(ReadableByteChannel channel) throws IOException {
  try (var reader = MessageReader.of(channel)) { //(1)
    // read some values
  }
}
  1. If no allocator is set when a reader (or writer) is created, an unpooled allocator with default options is used.
class Example {
  fun read(channel: ReadableByteChannel) {
    MessageReaders.of(channel).use { reader -> //(1)
      // read some values
    }
  }
}
  1. If no allocator is set when a reader (or writer) is created, an unpooled allocator with default options is used.

Use unpooled allocator#

class Example {
  final BufferAllocator allocator =
      BufferAllocator.ofUnpooled( options -> options //(1)
          .maxByteBufferCapacity(Integer.MAX_VALUE)  //(2)
          .maxCharBufferCapacity(Integer.MAX_VALUE)
      );

  void read(ReadableByteChannel channel) throws IOException {
    try (var reader = MessageReader.of(
        channel,
        options -> options.allocator(allocator)) //(3)
    ) { /* read some values */ }
  }

  void close() {
    allocator.close(); //(4)
  }
}
  1. Creates an allocator that returns a new buffer every time getByteBuffer() or getCharBuffer() is called.
  2. Sets allocator options by calling UnpooledOptionBuilder methods. All options are optional; this example shows their defaults.
  3. Sets the same allocator every time a message reader (or writer) is created. Allocators can be safely shared between multiple threads.
  4. When the allocator is no longer used, it should be closed.
class Example {
  val allocator: BufferAllocator = BufferAllocators.ofUnpooled( //(1)
    maxByteBufferCapacity = Integer.MAX_VALUE, //(2)
    maxCharBufferCapacity = Integer.MAX_VALUE
  )

  fun read(channel: ReadableByteChannel) {
    MessageReaders.of(channel, allocator = allocator).use { reader -> //(3)
      // read some values
    }
  }

  fun close() {
    allocator.close() //(4)
  }
}
  1. Creates an allocator that returns a new buffer every time getByteBuffer() or getCharBuffer() is called.
  2. Sets allocator options by setting named method parameters. All options are optional; this example shows their defaults.
  3. Sets the same allocator every time a message reader (or writer) is created. Allocators can be safely shared between multiple threads.
  4. When the allocator is no longer used, it should be closed.

Use pooled allocator#

class Example {
  final BufferAllocator allocator =
      BufferAllocator.ofPooled(options -> options   //(1)
          .maxByteBufferCapacity(Integer.MAX_VALUE) //(2)
          .maxCharBufferCapacity(Integer.MAX_VALUE)
          .maxPooledByteBufferCapacity(1024 * 1024)
          .maxPooledCharBufferCapacity(1024 * 512)
          .maxByteBufferPoolCapacity(1024 * 1024 * 64)
          .maxCharBufferPoolCapacity(1024 * 1024 * 32)
          .preferDirectBuffers(false)
      );

  void read(ReadableByteChannel channel) throws IOException {
    try (var reader = MessageReader.of(
        channel,
        options -> options.allocator(allocator)) //(3)
    ) { /* read some values */ }
  }

  void close() {
    allocator.close(); //(4)
  }
}
  1. Creates an allocator that reduces buffer allocations by maintaining a buffer pool.
  2. Sets allocator options by calling PooledOptionBuilder methods. All options are optional; this example shows their defaults.
  3. Sets the same allocator every time a message reader (or writer) is created. Allocators can be safely shared between multiple threads.
  4. When the allocator is no longer used, it should be closed to free its buffer pool.
class Example {
  val allocator: BufferAllocator = BufferAllocators.ofPooled( //(1)
    maxByteBufferCapacity = Integer.MAX_VALUE, //(2)
    maxCharBufferCapacity = Integer.MAX_VALUE,
    maxPooledByteBufferCapacity = 1024 * 1024,
    maxPooledCharBufferCapacity = 1024 * 512,
    maxByteBufferPoolCapacity = 1024 * 1024 * 64,
    maxCharBufferPoolCapacity = 1024 * 1024 * 32,
    preferDirectBuffers = false
  )

  fun read(channel: ReadableByteChannel) {
    MessageReaders.of(channel, allocator = allocator).use { reader -> //(3)
      // read some values
    }
  }

  fun close() {
    allocator.close() //(4)
  }
}
  1. Creates an allocator that reduces buffer allocations by maintaining a buffer pool.
  2. Sets allocator options by setting named method parameters. All options are optional; this example shows their defaults.
  3. Sets the same allocator every time a message reader (or writer) is created. Allocators can be safely shared between multiple threads.
  4. When the allocator is no longer used, it should be closed to free its buffer pool.

Kotlin Integration#

Read unsigned integers#

See Kotlin Integration.

Write unsigned integers#

See Kotlin Integration.