kotlinx-io

repository·master·Indexed 23 days ago

https://github.com/kotlin/kotlinx-io

A multiplatform Kotlin library providing high-performance basic IO primitives including Buffers, Sources, Sinks, and ByteString. Inspired by Okio, it utilizes segment pooling to reduce memory allocations and offers experimental filesystem support via the kotlinx.io.files package.

Tokens
3.8K
Snippets
7
Records
19
Agent score
81%

What's inside kotlinx-io

  1. Use ByteString for immutable byte sequences

    master
    The kotlinx-io-bytestring module provides kotlinx.io.bytestring.ByteString, which is an immutable sequence of bytes. It is designed for efficient handling of byte data and includes various extensions to facilitate working with byte sequences.
  2. How Source and Sink work in kotlinx-io

    master

    The primary way to interact with IO in kotlinx-io is through the Source and Sink interfaces.

    • Source: Provides buffered read operations for various types, including integer types, byte arrays, and strings.
    • Sink: Provides buffered write operations for various types.

    These interfaces are built on top of Buffer, RawSource, and RawSink. While Source and Sink are used for high-level buffered operations, RawSource and RawSink are intended for low-level integration with data providers like network interfaces or files.

    Buffer is a central component designed to be a highly optimized container that reduces memory allocations and avoids unnecessary data copying.

  3. How Buffer, Source, Sink, and ByteString work together

    master

    The kotlinx-io library is built around several core abstractions for handling byte sequences:

    • Buffer: A mutable sequence of bytes that acts like a queue. You can read data from its head or write data to its tail. It uses a linked list of segments to reduce memory allocations and allow efficient data sharing/delegation between buffers.
    • Source: An interface representing a data source (reading bytes).
    • Sink: An interface representing a data destination (writing bytes).
    • ByteString: An immutable sequence of bytes.

    Additionally, the library provides experimental filesystem support via the kotlinx.io.files package, using the FileSystem interface (with SystemFileSystem implementation) and the Path class.

  4. Run specific smoke test sets (Gradle or Maven)

    master

    The smoke tests are divided into two independent sets:

    1. Gradle projects: Run via the verifyGradleProjects task.
    2. Maven projects: Run via the verifyMavenProjects task.

    Both tasks are aggregated by the main smokeTest task. Note that the standard Gradle check and test tasks are no-op in this module.

  5. Thread-safety in kotlinx-io

    master
    Unless explicitly stated otherwise, types and functions provided by the kotlinx-io library are not thread-safe. If you are accessing a Source, Sink, or Buffer from multiple threads, you must provide your own synchronization mechanism.
  6. Implement RawSource and RawSink for custom integrations

    master
    If you need to integrate kotlinx-io with a data source or destination not currently supported by the library (such as a specific network interface or a custom hardware driver), you should implement the RawSource and RawSink interfaces. These interfaces serve as the low-level bridge between the library's buffered primitives and external data streams.
  7. Install kotlinx-io via Gradle

    master

    To use kotlinx-io in a Kotlin project, ensure mavenCentral() is included in your repositories.

    For standard JVM projects, add kotlinx-io-core to your dependencies. For multiplatform projects, add it to the commonMain source set to ensure availability across all targets.

    // In repositories block
    repositories {
        mavenCentral()
    }
    
    // In dependencies block for JVM
    dependencies {
        implementation("org.jetbrains.kotlinx:kotlinx-io-core:0.9.1")
    }
    
    // In multiplatform projects
    kotlin {
        sourceSets {
            commonMain {
                dependencies {
                    implementation("org.jetbrains.kotlinx:kotlinx-io-core:0.9.1")
                }
            }
        }
    }
  8. Run kotlinx-io smoke tests

    master

    Smoke tests verify that all artifacts are published correctly and that there are no dependency-related issues. You can run these tests using the :kotlinx-io-smoke-tests:smokeTest Gradle task.

    By default, the tests use the current project version. If you want to test against a specific version of kotlinx-io, use the smokeTest.kotlinxIoVersion property. If the version is unset, the task will use the current project version, which triggers local Maven repository usage and executes publication tasks before testing.

    To test against a specific version, use the -PsmokeTest.kotlinxIoVersion flag.

    ./gradlew :kotlinx-io-smoke-tests:smokeTest -PsmokeTest.kotlinxIoVersion=0.5.3-test
  9. Configure segment pooling on Android

    master

    To adjust the segment pool size on Android, you must set the kotlinx.io.pool.size.bytes system property in your Application.onCreate() method before any IO operations occur. You must also ensure your custom Application class is registered in your AndroidManifest.xml.

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools">
    
        <application 
           android:name="org.example.MySegmentHungryApp"
           ...
        >
    
        </application>
    </manifest>
  10. Customize Dokka HTML output with custom templates

    master
    You can customize Dokka's HTML output by providing a directory of custom templates. This is achieved by configuring the templatesDir property within the Dokka plugin configuration. This allows you to override default Dokka templates with your own designs to provide unified navigation or branding.
  11. Run kotlinx-io benchmarks on the JVM

    master

    To track the performance of the kotlinx-io implementation, you can run the benchmark suite using JMH (Java Microbenchmark Harness). First, build the benchmark JAR using the Gradle wrapper, then execute the JAR using the java -jar command.

    Note that the benchmark suite currently focuses on:

    • Core Buffer API usage (reading/writing primitive types, arrays, and UTF-8 strings).
    • Basic peek usage.
    • Segment pooling performance.
    ./gradlew :kotlinx-io-benchmarks:jvmJar
    
    java -jar benchmarks/build/benchmarks/jvm/jars/kotlinx-io-benchmarks-jvm-jmh-0.6.0-SNAPSHOT-JMH.jar  ReadStringBenchmark -f 1 -wi 5 -i 5 -tu us -w 1 -r 1