Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Возможности тулкита GTK+ и сопутствующих библиотек


Автор: А.Панин
Дата публикации: 3 декабря 2014 г.

Механизм для работы с файлами, содержащими пары ключ-значение

3. Открытие и закрытие файла

Для работы с файлом описанного формата должен быть создан объект типа GKeyFile. Этот объект создается с помощью функции g_key_file_new().
GKeyFile *g_key_file_new(void);
Возвращаемый в результате вызова данной функции объект не будет содержать никаких групп, комментариев и пар ключ-значение. Для того, чтобы разобрать содержимое файла, хранящегося на диске, следует использовать функцию g_key_file_load_from_file():
gboolean g_key_file_load_from_file(GKeyFile *key_file, 
                                   const gchar *file, 
                                   GKeyFileFlags flags, 
                                   GError **error);

В качестве аргумента flags может быть передана битовая маска из флагов операции открытия файла. Флаг G_KEY_FILE_KEEP_COMMENTS может быть использован для загрузки комментариев, а флаг G_KEY_FILE_KEEP_TRANSLATIONS - для загрузки локализованных значений. В том случае, если вы не используете подобные данные (а в случае сохранения данных конфигурации приложения они наверняка не используются), вы можете передать флаг G_KEY_FILE_NONE. В том случае, если вас интересует сообщение об ошибке в случае неудачной загрузки данных из файла, вы также можете передать указатель на объект ошибки типа GError, в противном случае следует передавать значение NULL.

Для разбора файла из пользовательской и системных директорий поиска файлов данных, обозначенных в рамках спецификации XDG Base Directory Specification как XDG_DATA_HOME и XDG_DATA_DIRS соответственно, может быть использована функция g_key_file_load_from_data_dirs():
gboolean g_key_file_load_from_data_dirs(GKeyFile *key_file, 
                                        const gchar *file, 
                                        gchar **full_path, 
                                        GKeyFileFlags flags, 
                                        GError **error);

В случае использования данной функции имя файла должно передаваться в качестве аргумента file, а в случае удачного открытия файла полный путь к нему будет возвращен с помощью аргумента full_path.

Также существует аналогичная функция g_key_file_load_from_dirs(), отличающаяся от приведенной выше только тем, что разработчик может самостоятельно задать директории для поиска файлов:
gboolean g_key_file_load_from_dirs(GKeyFile *key_file, 
                                   const gchar *file, 
                                   const gchar **search_dirs, 
                                   gchar **full_path, 
                                   GKeyFileFlags flags, 
                                   GError **error);

В данном случае список директорий следует передавать в качестве аргумента search_dirs.

Не стоит забывать также о функции g_key_file_load_from_data(), позволяющей загружать содержимое файла из памяти. Она может быть полезна, к примеру, в том случае, если файл отображается в память.
gboolean g_key_file_load_from_data(GKeyFile *key_file, 
                                   const gchar *data, 
                                   gsize length, 
                                   GKeyFileFlags flags, 
                                   GError **error);

Для загрузки данных файла из памяти следует передать адрес фрагмента памяти с данными файла в качестве аргумента data, а длину этого фрагмента - в качестве аргумента length. Значение аргумента length может быть равно -1 в том случае, если расположенное в памяти строковое представление файла завершается нулевым символом.

Существует и обратная функция g_key_file_to_data(), которая возвращает строковое представление файла и длину этого представления:
gchar *g_key_file_to_data(GKeyFile *key_file, 
                          gsize *length, 
                          GError **error);

Данная функция используется главным образом в момент сохранения данных в файл на диске совместно с функцией для сохранения данных из памяти в файл g_file_set_contents(), о которой будет сказано позднее. Возвращаемое строковое представление сохраняется в резервируемом фрагменте памяти, поэтому эта память должна быть освобождена с помощью функции g_free() после того, как строковое представление будет сохранено в файле.

Объект файла, содержащего пары ключ-значение, имеет счетчик ссылок, значение которого может увеличиваться и уменьшаться на 1 с помощью функций g_key_file_ref() и g_key_file_unref() соответственно.
GKeyFile *g_key_file_ref(GKeyFile *key_file);
void g_key_file_unref(GKeyFile *key_file);

Сразу же после создания объекта значение счетчика ссылок равно 1, а в случае равенства значения счетчика ссылок 0 происходит уничтожение объекта.

После того, как работа с объектом завершается, он может быть явно уничтожен с помощью функции g_key_file_free().
void g_key_file_free(GKeyFile *key_file);
В том случае, если вы создаете новый файл и хотите использовать специфический разделитель для элементов массивов значений, вы можете использовать функцию g_key_file_set_list_separator():
void g_key_file_set_list_separator(GKeyFile *key_file, 
                                   gchar separator);

Обычно в качестве разделителей используются символы ";" или ",".

4. Работа с данными

После создания объекта и загрузки данных из файла с диска можно приступить непосредственно к работе с данными. В некоторых случаях может оказаться полезным список групп, который может быть получен с помощью функции g_key_file_get_groups():
gchar **g_key_file_get_groups(GKeyFile *key_file, 
                              gsize *length);
Функция вернет массив срок, после работы с которым придется освободить зарезервированную для хранения строк память с помощью функции g_strfreev(). С помощью аргумента length будет возвращено значение длины массива, впрочем, без него вполне можно обойтись, передав значение NULL. В этом случае для обхода массива строк groups и вывода каждой из строк может быть использован следующий код:
gint i = 0;
while (groups[i] != NULL) {
	g_printf("%s\n", groups[i]);
}
Список ключей для каждой из групп может быть получен аналогичным образом с помощью функции g_key_file_get_keys():
gchar **g_key_file_get_keys(GKeyFile *key_file, 
                            const gchar *group_name, 
                            gsize *length, 
                            GError **error);

Название группы должно передаваться с помощью аргумента group_name. В случае отсутствия указанной группы наряду с результирующим значением NULL будет возвращена ошибка с идентификатором G_KEY_FILE_ERROR_GROUP_NOT_FOUND.

Для проверки наличия групп и ключей могут использоваться функции g_key_file_has_group() и g_key_file_has_key() соответственно:
gboolean g_key_file_has_group(GKeyFile *key_file, 
                              const gchar *group_name);
gboolean g_key_file_has_key(GKeyFile *key_file, 
                            const gchar *group_name, 
                            const gchar *key, 
                            GError **error);

Название группы также передается с помощью аргумента group_name, название ключа - с помощью аргумента key. Данные имена аргументов используются во всех функциях данного класса.

Остальные функции объекта могут быть разделены на три группы:
  1. Функции для получения значений.
  2. Функции для установки значений.
  3. Функции для удаления значений.

Рассмотрим функции для установки значений и соответствующие им функции для получения значений. Вы можете познакомиться с полными описаниями этих функций, обратившись либо к документации API в сети, либо к приложению для просмотра локальной копии документации API под названием Devhelp.

Таблица 1. Функции для установки и получения значений
Функция для установки значения Функция для получения значения Описание
g_key_file_get_value() g_key_file_set_value() Установка/получение необработанного строкового представления значения
g_key_file_get_string() g_key_file_set_string() Установка/получение строкового значения с обработкой специальных последовательностей символов
g_key_file_get_locale_string() g_key_file_set_locale_string() Установка/получение строкового значения для заданной локализации
g_key_file_get_boolean() g_key_file_set_boolean() Установка/получение логического значения
g_key_file_get_integer() g_key_file_set_integer() Установка/получение знакового целочисленного значения
g_key_file_get_int64() g_key_file_set_int64() Установка/получение 64-битного знакового целочисленного значения
g_key_file_get_uint64() g_key_file_set_uint64() Установка/получение 64-битного беззнакового целочисленного значения
g_key_file_get_double() g_key_file_set_double() Установка/получение значения с плавающей точкой
g_key_file_get_string_list() g_key_file_set_string_list() Установка/получение массива строковых значений
g_key_file_get_locale_string_list() g_key_file_set_locale_string_list() Установка/получение массива строковых значений для заданной локализации
g_key_file_get_boolean_list() g_key_file_set_boolean_list() Установка/получение массива логических значений
g_key_file_get_integer_list() g_key_file_set_integer_list() Установка/получение массива целочисленных значений
g_key_file_get_double_list() g_key_file_set_double_list() Установка/получение массива значений с плавающей точкой
g_key_file_get_comment() g_key_file_set_comment() Установка/получение комментария для заданного ключа, заданной группы или всего файла

В том случае, если при использовании функций для установки значений не обнаруживается заданного ключа или заданной группы, они создаются автоматически.

Таблица 2. Функции для удаления значений
Функция Описание
g_key_file_remove_group() Удаление заданной группы вместе с ключами и значениями
g_key_file_remove_key() Удаление заданного ключа из заданной группы вместе с его значением
g_key_file_remove_comment() Удаление комментария, соответствующего заданному ключу, заданной группе или всему файлу

Продолжение статьи : 5. Пример использования.