Skip to content

sesquialtera87/K-Ini

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

62 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

K-INI

kotlin %237F52FF java %23ED8B00 Compatibility Java 11%2B informational License MIT yellow K Ini

A Kotlin/Java library to read and write INI files (requires Java 11 or above).

File format

An INI file is a text-based configuration file organised in key-value pairs of properties and sections organising them.

Key-Value pairs

K-INI recognizes as a valid key char every character different from = and :, as the equal sign and the colon are recognized as delimiters between the key and the value.

Note
Leading and trailing whitespaces in the key name are ignored.
Caution
A key name can also contain whitespaces, even though that practice isn’t recommended.

The value is formed by all the characters after the delimiter, until the end of the line (or the beginning of an inline comment).

Note
As for keys, leading and trailing whitespaces are ignored.

Values are allowed to be quoted, through single or double quotes, like strings in some programming languages (key1="value 1",key2='value 2'). This permits to preserve all whitespaces and to use character escaping. If a value is quoted, the final and ending quotes are not considered as part of the value.

Important
K-INI actually treats an INI file line by line, so every syntactical element of the file cannot span more than one line. Multiline values can be stored through quotation and escaping each line feed \n in the string.

Sections

Key-value pairs can be grouped under a section. A section can be declared on a line by itself, by enclosing its name in square brackets: [A Section]. There’s no explicit end-of-section delimiter, so the section declaration applies to all pairs below it, until another section is declared.

Note
Leading and trailing whitespaces in the section name are ignored, so that [HTTP] and [ HTTP ] declare all the same section named HTTP.

Not every key-value pair has to belong to a section. K-INI supports the so-called global properties, that is ungrouped pairs declared at the start of the file, before any section declaration.

property = "I'm a global one"

[section]
a = 2

Comments

A line starting with # or ; is a comment. All chars encountered until the end of the line are discarded from the parser. As previously noted, nothing can span more than one line, so multiline comments are not recognised. Every line that is to be understood as a comment has to start with one of the comment markers.

K-INI accepts also inline comments, placed after a section declaration or a key-value pair.

# a comment
[section]
a = 2   ; inline comment...

Usage

Working with .ini files

An .ini file is represented by an instance of the class org.mth.kini.Ini, describing sections and properties contained in the .ini file. Instances of the org.mth.kini.Ini class can be obtained in two ways:

  • Instantiate an object through the default constructor val ini = Ini().

  • Using the idiomatioc ini { …​ } DSL block helper function.

val ini = ini {
    section("Section 1") {
        set("property 1", "value 1")
        set("property 2", "value 2")
    }
    "Section 2" {
        "property 1" to "value 1"
        "property 2" to "value 2"
    }
}

Existing .ini files can be loaded into an Ini object through one of the load functions.

val ini = Ini.load(Path.of("test/sample.ini"))

The content of an Ini object can be stored to the local filesystem with a call to the store function.

ini.store(Path.of("test/sample.ini"))

Sections

Use hasSection(name: String) or the idiomatic Kotlin in operator to check if a section is present.

if ("my-section" in ini) {
    // ...
}

The function section(name: String) retrieves a named section, or automatically creates it if missing.

val section: IniSection = ini.section("my-section")
Note
Empty sections are not written to the file during the saving process.

A section can be removed by calling removeSection(name: String).

Properties and Data Types

IniSection behaves like a map. To insert or access values, you can use traditional methods or index operators:

val value = section["my-property"]      // get a property value
section["my-property"] = "new value"    // set a property value

To avoid manual casts, IniSection offers strongly-typed getters for primitives (returning fallbacks if requested):

  • getBoolean(name, default)

  • getShort(name, default)

  • getInt(name, default)

  • getLong(name, default) (supports literal suffixes like 100L)

  • getDouble(name, default)

  • getFloat(name, default)

Array Support

Properties enclosed in brackets (e.g., list = [a, b, c]) can be parsed directly into typed arrays:

val strings: Array<String> = section.getArray("str_list")
val integers: Array<out Number> = section.getNumberArray("int_list", Int::class.java)

Advanced Hierarchical Features

K-INI natively supports dot-separated hierarchical structures for keys and sections, allowing deep data navigation.

Section Trees

If you use dot-notation for sections (e.g., [db.mysql], [db.postgres]), you can explore nodes dynamically:

// Returns next-level tokens. e.g., ini.getSectionNodes("db") -> ["mysql", "postgres"]
val subNodes = ini.getSectionNodes("db")

// Returns a filtered map of sections stripping the prefix
val dbGroup: Map<String, IniSection> = ini.getSectionGroup("db")

Property Trees

Similarly, flat properties within a single section can be treated as a tree structure using dot-separated keys (e.g., db.host = localhost):

// Groups entries by their first token before the dot
val tree: Map<String, Map<String, String>> = section.groupByRoot()

// Filters and extracts a specific subgroup of properties
val dbConfig = section.getGroup("db", stripPrefix = true) // {"host" -> "localhost"}

Installation

K-INI is distributed via JitPack. You can include it in your project by adding the repository and the dependency to your build configuration.

Note
Here X.Y.Z stands for the latest library release version, available in the GitHub page.

Gradle (Kotlin DSL)

Add the JitPack repository to your build.gradle.kts:

repositories {
    mavenCentral()
    maven { url = uri("https://jitpack.io") }
}

Then, add the dependency:

dependencies {
    implementation("com.github.sesquialtera87:K-Ini:X.Y.Z")
}

Maven

Add the JitPack repository to your pom.xml:

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

Then, add the Maven dependency:

<dependency>
    <groupId>com.github.sesquialtera87</groupId>
    <artifactId>K-Ini</artifactId>
    <version>X.Y.Z</version>
</dependency>

License

Distributed under the MIT License.

About

Handle .ini files in Kotlin/Java

Topics

Resources

License

Stars

7 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors