Опубликован: 22.12.2015 | Уровень: для всех | Доступ: платный
Лекция 11:

Чтение и запись текстовых файлов

< Лекция 10 || Лекция 11 || Лекция 12 >

Чтение текстовых файлов

Если вы хотите читать или записывать текстовые файлы, используйте структуру 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.


< Лекция 10 || Лекция 11 || Лекция 12 >