KeyFile


Object Hierarchy:

GLib.KeyFile GLib.KeyFile GLib.KeyFile

Description:

[ Compact ]
[ Version ( since = "2.32" ) ]
[ CCode ( ref_function = "g_key_file_ref" , type_id = "G_TYPE_KEY_FILE" , unref_function = "g_key_file_unref" ) ]
public class KeyFile

`GKeyFile` parses .

ini-like config files.

`GKeyFile` lets you parse, edit or create files containing groups of key-value pairs, which we call "key files" for lack of a better name. Several freedesktop.org specifications use key files now, e.g the Desktop Entry Specification and the Icon Theme Specification .

The syntax of key files is described in detail in the Desktop Entry Specification, here is a quick summary: Key files consists of groups of key-value pairs, interspersed with comments.

```txt

this is just an example

there can be comments before the first group

[First Group]

Name=Key File Example\tthis value shows\nescaping

localized strings are stored in multiple key-value pairs

Welcome=Hello Welcome[de]=Hallo Welcome[fr_FR]=Bonjour Welcome[it]=Ciao

[Another Group]

Numbers=2;20;-200;0

Booleans=true;false;true;true ```

Lines beginning with a '#' and blank lines are considered comments.

Groups are started by a header line containing the group name enclosed in '[' and ']', and ended implicitly by the start of the next group or the end of the file. Each key-value pair must be contained in a group.

Key-value pairs generally have the form `key=value`, with the exception of localized strings, which have the form `key[locale]=value`, with a locale identifier of the form `lang_COUNTRY@MODIFIER` where `COUNTRY` and `MODIFIER` are optional. Space before and after the '=' character are ignored. Newline, tab, carriage return and backslash characters in value are escaped as `\n`, `\t`, `\r`, and `\\\\`, respectively. To preserve leading spaces in values, these can also be escaped as `\s`.

Key files can store strings (possibly with localized variants), integers, booleans and lists of these. Lists are separated by a separator character, typically ';' or ','. To use the list separator character in a value in a list, it has to be escaped by prefixing it with a backslash.

This syntax is obviously inspired by the .ini files commonly met on Windows, but there are some important differences:

  • .ini files use the ';' character to begin comments, key files use the '#' character.
  • Key files do not allow for ungrouped keys meaning only comments can precede the first group.
  • Key files are always encoded in UTF-8.
  • Key and Group names are case-sensitive. For example, a group called [GROUP] is a different from [group].
  • .ini files don't have a strongly typed boolean entry type, they only have GetProfileInt. In key files, only true and false ( in lower case) are allowed.

Note that in contrast to the Desktop Entry Specification, groups in key files may contain the same key multiple times; the last entry wins. Key files may also contain multiple groups with the same name; they are merged together. Another difference is that keys and group names in key files are not restricted to ASCII characters.

Here is an example of loading a key file and reading a value:

```c g_autoptr(GError) error = NULL; g_autoptr(GKeyFile) key_file = g_key_file_new ();

if (!g_key_file_load_from_file (key_file, "key-file.ini", flags, &error)) { if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT )) g_warning ("Error loading key file: s", error->message); return; }

g_autofree gchar *val = g_key_file_get_string (key_file, "Group Name", "SomeKey", &error); if (val == NULL && !g_error_matches ( error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) { g_warning ("Error finding key in key file: s", error->message); return; } else if (val == NULL) { // Fall back to a default value. val = g_strdup ("default-value"); } ```

Here is an example of creating and saving a key file:

```c g_autoptr(GKeyFile) key_file = g_key_file_new (); const gchar *val = …; g_autoptr(GError) error = NULL;

g_key_file_set_string (key_file, "Group Name", "SomeKey", val);

// Save as a file. if (!g_key_file_save_to_file (key_file, "key-file.ini", &error)) { g_warning ("Error saving key file: s", error->message); return; }

// Or store to a GBytes for use elsewhere. gsize data_len; g_autofree guint8 *data = (guint8 *) g_key_file_to_data (key_file, &data_len, &error); if (data == NULL) { g_warning ("Error saving key file: s", error->message); return; } g_autoptr(GBytes) bytes = g_bytes_new_take (g_steal_pointer (&data), data_len); ```

Example: KeyFile handling:

public static int main (string[] args) {
try {
//
// Read data:
//

KeyFile file = new KeyFile ();

// Use ',' as array-element-separator instead of ';'.
file.set_list_separator (',');

// file.load_from_file ("my-keyfile.conf", KeyFileFlags.NONE);
file.load_from_data ("""
# This is an example key-value file

[OptionalGroup]
required_key = myreq
optional_key = myopt

[BasicValues]
String=mystr
Bool=true
Int=300
Double=0.0

[Lists]
BoolArray=true,true,false
StringArray=Str1,Str2

[LocalizedString]
Hi=Hello
Hi[fr]=Bonjour
Hi[de]=Hallo
Hi[es]=Hola
"""
, -1, KeyFileFlags.NONE);

// ** BasicValues:
string @string = file.get_string ("BasicValues", "String");
bool @bool = file.get_boolean ("BasicValues", "Bool");
int @int = file.get_integer ("BasicValues", "Int");
double @double = file.get_double ("BasicValues", "Double");

// Output:
// ``mystr``
// ``true``
// ``300``
// ``0.000000``
print ("%s\n", @string);
print ("%s\n", @bool.to_string ());
print ("%d\n", @int);
print ("%f\n", @double);

// ** Lists:
bool[] bool_array = file.get_boolean_list ("Lists", "BoolArray");
string[] string_array = file.get_string_list ("Lists", "StringArray");

// Output: ``true true false``
foreach (bool b in bool_array) {
print ("%s ", b.to_string ());
}
print ("\n");

// Output: ``"Str1" "Str2"``
foreach (string str in string_array) {
print ("\"%s\" ", str);
}
print ("\n");

// ** LocalizedString:
string hi = file.get_locale_string ("LocalizedString", "Hi", null);
// Output: ``Hello``
print ("%s\n", hi);


// ** OptionalGroup
// Check availability before accessing to avoid exceptions:
if (file.has_group ("OptionalGroup")) {
string required_key = file.get_string ("OptionalGroup", "required_key");
string? optional_key = null;
if (file.has_key ("OptionalGroup", "optional_key")) {
optional_key = file.get_string ("OptionalGroup", "optional_key");
}

// Output:
// ``myreq``
// ``myopt``
print ("%s\n", required_key);
print ("%s\n", optional_key);
}

//
// Modify data:
//

file.set_string ("BasicValues", "String", "my-new-value");
file.remove_group ("LocalizedString");
file.remove_group ("OptionalGroup");
file.remove_key ("Lists", "StringArray");


//
// List all groups & keys:
//

// Output:
// ``Key: BasicValues.String = my-new-value``
// ``Key: BasicValues.Bool = true``
// ``Key: BasicValues.Int = 300``
// ``Key: BasicValues.Double = 0.0``
// ``Key: Lists.BoolArray = true,true,false``

foreach (unowned string group in file.get_groups ()) {
foreach (unowned string key in file.get_keys (group)) {
print ("Key: %s.%s = %s\n", group, key, file.get_value (group, key));
}
}

//
// Print the modified keyfile to stdout:
//

// Output:
// ``-----``
// ``[BasicValues]``
// ``String=my-new-value``
// ``Bool=true``
// ``Int=300``
// ``Double=0.0``
// ````
// ``[Lists]``
// ``BoolArray=true,true,false``
// ``----``
string keyfile_str = file.to_data ();
print ("-----\n%s----\n", keyfile_str);
} catch (KeyFileError e) {
print ("Error: %s\n", e.message);
}
return 0;
}

valac --pkg glib-2.0 GLib.KeyFile.vala


Namespace: GLib
Package: glib-2.0

Content:

Creation methods:

Methods: