Чтение и запись текстовых файлов
Чтение текстовых файлов
Если вы хотите читать или записывать текстовые файлы, используйте структуру FILE. Вы сможете читать файлы из папки /res, но не сможете записывать их. Файлы в папке /data доступны как для чтения, так и для записи.
Теперь мы попытаемся прочитать текстовые файлы из папки /res и отобразить их на экране.
Создайте новое приложение 'TextFileView'. После создания проекта скопируйте файл text.txt в папку /res вашего проекта. Файл text.txt содержит приветствие на разных языках:
Откройте файл исходного кода и внесите следующие изменения в структуру appdata
typedef struct appdata { Evas_Object *win; Evas_Object *conform; //Evas_Object *label; Evas_Object *entry; } appdata_s;
Мы добавили переменные поля ввода. Создайте две функции выше create_base_gui().
static void my_table_pack(Evas_Object *table, Evas_Object *child, int col, int row, int spanx, int spany, double h_expand, double v_expand, double h_align, double v_align) { /* Create a frame around the child, for padding */ Evas_Object *frame = elm_frame_add(table); elm_object_style_set(frame, "pad_small"); evas_object_size_hint_weight_set(frame, h_expand, v_expand); evas_object_size_hint_align_set(frame, h_align, v_align); /* place child in its box */ { evas_object_size_hint_weight_set(child, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(child, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_object_content_set(frame, child); evas_object_show(child); } elm_table_pack(table, frame, col, row, spanx, spany); evas_object_show(frame); } static Evas_Object * my_button_add(Evas_Object *parent, const char *text, Evas_Smart_Cb cb, void *cb_data) { Evas_Object *btn; btn = elm_button_add(parent); elm_object_text_set(btn, text); evas_object_smart_callback_add(btn, "clicked", cb, cb_data); return btn; }
my_table_pack() - это функция, которая добавляет элемент управления к контролу Table.
my_button_add() - это функция, которая создает кнопку. Далее, перейдите в функцию create_base_gui() и добавьте код для создания таких контролов, как Frame, Table, Button и Entry. Аннотируйте код создания метки.
/* Conformant */ ad->conform = elm_conformant_add(ad->win); elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW); elm_win_indicator_opacity_set(ad->win, ELM_WIN_INDICATOR_OPAQUE); evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); elm_win_resize_object_add(ad->win, ad->conform); evas_object_show(ad->conform); { Evas_Object *tbl, *btn, *frame; /* Frame */ frame = elm_frame_add(ad->win); elm_object_style_set(frame, "pad_medium"); elm_object_content_set(ad->conform, frame); evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(frame); /* Container: standard table */ tbl = elm_table_add(ad->win); evas_object_size_hint_weight_set(tbl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(tbl, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_object_content_set(frame, tbl); evas_object_show(tbl); { /* Button-1 */ btn = my_button_add(ad->conform, "Read", btn_read_cb, ad); my_table_pack(tbl, btn, 0, 0, 1, 1, EVAS_HINT_EXPAND, 0.0, EVAS_HINT_FILL, EVAS_HINT_FILL); /* Entry */ ad->entry = elm_entry_add(ad->conform); elm_entry_scrollable_set(ad->entry, EINA_TRUE); elm_object_signal_emit(ad->entry, "elm,state,scroll,enabled", ""); elm_object_text_set(ad->entry, "Please press <b>Read</> button"); my_table_pack(tbl, ad->entry, 0, 1, 2, 1, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND, EVAS_HINT_FILL, EVAS_HINT_FILL); } } /* Show window after base gui is set up */ evas_object_show(ad->win); }
Добавьте две функции выше create_base_gui().
static void app_get_resource(const char *res_file_in, char *res_path_out, int res_path_max) { char *res_path = app_get_resource_path(); if (res_path) { snprintf(res_path_out, res_path_max, "%s%s", res_path, res_file_in); free(res_path); } } static void btn_read_cb(void *data, Evas_Object *obj, void *event_info) { appdata_s *ad = data; char filepath[PATH_MAX] = { 0, }; Eina_File *f; app_get_resource("text.txt", filepath, PATH_MAX); f = eina_file_open(filepath, EINA_FALSE); if (!f) { elm_object_text_set(ad->entry, "File not found!"); return; } elm_entry_file_set(ad->entry, filepath, ELM_TEXT_FORMAT_MARKUP_UTF8); eina_file_close(f); }
app_get_resource() - это функция, которая запрашивает абсолютный путь файла, сохраненного в папке /res, и возвращает его.
btn_read_cb() - это обработчик нажатия кнопки. После нажатия на кнопку происходит запрос пути к текстовому файлу и ввод его в элемент управления Entry.
eina_file_open() - это API, который открывает файл и возвращает объект Eina_File. Допускается только чтение.
elm_entry_file_set() - это API, который соединяет контрол Entry с текстовым файлом.
Содержимое текстового файла вводится и отображается в контроле Entry. В качестве третьего параметра задается текстовый формат. Использование параметра ELM_TEXT_FORMAT_MARKUP_UTF8 делает возможным использование формата UTF8.
eina_file_close() - это API, который закрывает файловый объект в формае Eina_File.
Постройте приложение. Нажмите на кнопку Read, в контроле Entry отобразятся приветствия на разных языках.
Запись текстового файла
Мы попытаемся реализовать возможность сохранения текста после нажатия на кнопку. Папка /res не позволяет записывать файлы. Таким образом, мы должны сохранять файлы в папке /data. Добавьте код, создающий вторую кнопку в функции create_base_gui().
{ /* Button-1 */ btn = my_button_add(ad->conform, "Read", btn_read_cb, ad); my_table_pack(tbl, btn, 0, 0, 1, 1, EVAS_HINT_EXPAND, 0.0, EVAS_HINT_FILL, EVAS_HINT_FILL); /* Button-2 */ btn = my_button_add(ad->conform, "Write", btn_write_cb, ad); my_table_pack(tbl, btn, 1, 0, 1, 1, EVAS_HINT_EXPAND, 0.0, EVAS_HINT_FILL, EVAS_HINT_FILL); /* Entry */ ad->entry = elm_entry_add(ad->conform); elm_entry_scrollable_set(ad->entry, EINA_TRUE); elm_object_signal_emit(ad->entry, "elm,state,scroll,enabled", ""); elm_object_text_set(ad->entry, "Please press <b>Read</> button"); my_table_pack(tbl, ad->entry, 0, 1, 2, 1, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND, EVAS_HINT_FILL, EVAS_HINT_FILL); } }
Для сохранения текста в файле, добавьте третью функцию выше create_base_gui().
static void app_get_data(const char *res_file_in, char *res_path_out, int res_path_max) { char *res_path = app_get_data_path(); if (res_path) { snprintf(res_path_out, res_path_max, "%s%s", res_path, res_file_in); free(res_path); } } static char* write_file(const char* filepath, const char* buf) { FILE *fp; fp = fopen(filepath, "w"); fputs(buf, fp); fclose(fp); } static void btn_write_cb(void *data, Evas_Object *obj, void *event_info) { appdata_s *ad = data; char* buf = elm_entry_entry_get(ad->entry); char filepath[PATH_MAX] = { 0, }; app_get_data("text.txt", filepath, PATH_MAX); write_file(filepath, elm_entry_entry_get(ad->entry)); elm_entry_file_set(ad->entry, filepath, ELM_TEXT_FORMAT_MARKUP_UTF8); }
app_get_data() - это функция, которая возвращает абсолютный путьк файлу, существующему в папке /data.
app_get_data_path() - это API, который возвращает абсолютный путь папки /data.
write_file() - это функция, которая сохраняет текстовые данные в файле.
fputs(char *, FILE *) - это API, который сохраняет текстовые данные в Filestream.
btn_write_cb() - это обработчик нажатия второй кнопки. Запрашивает абсолютный путь папки /data и сохраняет текстовые данные, введенные в контрол Entry в файл.
Запустите проект снова. Нажмите на кнопку Read и вызовите файл, измените содержимое контрола Entry и нажмите на кнопку Write. Теперь измененное содержимое сохранено в папке /data.