Evgenii Legotckoi
Evgenii Legotckoi30 июля 2015 г. 21:06

Файл в ОС Android. Операции чтения и записи

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

Структура проекта

Эстетических изменений стандартных кнопок или ListView в данном уроке производиться не будет, поскольку мы будем работать с тем, что скрыто от глаз пользователя, а именно работать с файлами.

Вся структура проекта соответственно состоит на этот раз лишь из одного класса: MainActivity

Также в проекте присутствуют следующие файлы ресурсов:

  1. activity_main.xml
  2. strings.xml
  3. styles.xml - в данном файле отсутствуют какие-либо изменения относящиеся к проекту.

Кроме этого внесены изменения в файл AndroidManifest.xml. В файле необходимо добавить следующие две строки. Это разрешения для приложения - производить операции чтения и записи с внешним накопителем (то есть SD Card телефона) В современным смартфонах на базе ОС Android в большинстве случаев запись информации производится во внешний накопитель, хотя обычный пользователь считает этот накопитель внутренним, поскольку он является встроенным, но с точки зрения операционной систем данный накопитель (то есть SD Card) является внешним накопителем. В данной статье не будет рассматриваться вариант работы с истинно внутренним накопителем.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="ru.evileg.workwithfiles" >

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

...

</manifest>

Формирование разметки приложения

activity_main.xml

Разметка основной активити, в которой будет производиться работа нашего приложения. В данной разметке присутствует всего две кнопки (Button) и текстовое поле (TextView), в которое мы будем выводить информацию сохранённую в файле.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:background="#ffffff"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/write_file"
        android:id="@+id/buttonWrite"
        android:layout_gravity="center_horizontal" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/read_file"
        android:id="@+id/buttonRead"
        android:layout_gravity="center_horizontal" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/textView"
        android:textSize="26sp"
        android:layout_gravity="center_horizontal" />
</LinearLayout>

strings.xml

Файл ресурсов текста в ОС Android. Подготовка всех строк, которые применяются в Вашем Приложении в данном файле, является не только хорошим тоном, но обязательным условием для разработки качественного Приложения. Поскольку, если вы будете дисциплинировать себя, сохранять всю подобную информацию в данном файле, то впоследствии это окупится, когда вы будете производить перевод Приложения на другие языки. Тем более, что в Android Studio имеется удобный функционал для этого.

<resources>
    <string name="app_name">Work With Files</string>

    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>

    <string name="write_done">Запись выполнена</string>
    <string name="write_file">Записать данные в файл</string>
    <string name="read_file">Считать данные из файла</string>
</resources>

styles.xml

В данном файле нет изменений относящихся к проекту. Но при создании проекта стандартная тема оформления не рендерится Android Studio. Выдается ошибки при предпросмотре и в режиме дизайна. Чтобы этого избежать, пропишите следующую информацию взамен старой.

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Base.Theme.AppCompat.Light"/>

</resources>

Основной класс проекта - MainActivity.java

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

package ru.evileg.workwithfiles;

import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;


public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    /*
     * Создаем постоянные константы для удобства работы,
     * объявляем TextView, который должен быть доступен в нескольких методах класса
     */
    private static final String fileName = "hello.txt";
    private static final String text = "Hello World";
    private static TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /*
         * Объявляем и инциализируем Кнопки (Button),
         * а также инициализируем TextView
         * Также в активити имплементирован метод слушателя событий нажатия,
         * то есть OnClickListener, который привязывается к кнопкам
         */
        textView = (TextView) this.findViewById(R.id.textView);
        Button buttonWrite = (Button) this.findViewById(R.id.buttonWrite);
        Button buttonRead = (Button) this.findViewById(R.id.buttonRead);
        buttonWrite.setOnClickListener(this);
        buttonRead.setOnClickListener(this);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    /*
     * Обработчик нажатий кнопок. Нажатая кнопка определяется по её ID через метод getID()
     */
    @Override
    public void onClick(View v) {

        switch (v.getId()){
            case R.id.buttonWrite:
                writeFile();
                break;
            case R.id.buttonRead:
                readFile();
                break;
            default:
                break;
        }
    }

    private void writeFile() {
        try {
            /*
             * Создается объект файла, при этом путь к файлу находиться методом класcа Environment
             * Обращение идёт, как и было сказано выше к внешнему накопителю
             */
            File myFile = new File(Environment.getExternalStorageDirectory().toString() + "/" + fileName);
            myFile.createNewFile();                                         // Создается файл, если он не был создан
            FileOutputStream outputStream = new FileOutputStream(myFile);   // После чего создаем поток для записи
            outputStream.write(text.getBytes());                            // и производим непосредственно запись
            outputStream.close();
            /*
             * Вызов сообщения Toast не относится к теме.
             * Просто для удобства визуального контроля исполнения метода в приложении
             */
            Toast.makeText(this, R.string.write_done, Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void readFile() {
        /*
         * Аналогично создается объект файла
         */
        File myFile = new File(Environment.getExternalStorageDirectory().toString() + "/" + fileName);
        try {
            FileInputStream inputStream = new FileInputStream(myFile);
            /*
             * Буфферезируем данные из выходного потока файла
             */
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            /*
             * Класс для создания строк из последовательностей символов
             */
            StringBuilder stringBuilder = new StringBuilder();
            String line;
            try {
                /*
                 * Производим построчное считывание данных из файла в конструктор строки,
                 * Псоле того, как данные закончились, производим вывод текста в TextView
                 */
                while ((line = bufferedReader.readLine()) != null){
                    stringBuilder.append(line);
                }
                textView.setText(stringBuilder);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Итог

Если в процессе изучения материала не возникло никаких проблем и ошибок, то по нажатию кнопки записи в файл произойдет создание нового файла и будет произведена запись строки "Hello World". При нажатии кнопки чтения будет выведена информация сохранённая в текстовом файле. Процесс показан на скриншотах ниже.

По нажатию кнопки производится запись в файл информации

Запись в файл

Чтение из файла производится по нажатию соответствующей кнопки. При этом в TextView выводится текст

Созданный файл hello.txt в файловом менеджере

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

A
  • 6 ноября 2017 г. 9:18

Как я понял данное приложение сохраняет текст в один единственный файл - hello.txt. Хотел бы узнать как можно реализовать функцию создания новый текстовых файлов и их переименования, т.е после нажатия на кнопку сохранения будет создаваться новый текстовый файл, пользователь будет выбирать куда не телефоне его сохранить и сам же вводит имя файла. А так же как реализовать функцию выбора из каталога файлов, т. е при нажатие на кнопку "считать из файла" открывалась бы папка в которой у пользователя находятся другие текстовые документы и он мог их редактировать последующего редактирования.

Evgenii Legotckoi
  • 6 ноября 2017 г. 14:41

эххх... как это было давно и не правда )))) я с тех пор (через пару месяцев после этой статьи +-) на Java и не писал больше.
Вот если меня накроет не по-детски и я всё-таки начну писать сравнительные статьи Android: Java vs Qt , вот тогда что-нибудь интересное и вывалится на эту тему. А так пока... даже не знаю, что Вам ответить.

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
MB

Qt - Тест 001. Сигналы и слоты

  • Результат:57баллов,
  • Очки рейтинга-2
MB

C++ - Тест 001. Первая программа и типы данных

  • Результат:60баллов,
  • Очки рейтинга-1
GK

C++ - Тест 005. Структуры и Классы

  • Результат:0баллов,
  • Очки рейтинга-10
Последние комментарии
J
JonnyJo8 июня 2023 г. 12:14
Qt/C++ - Урок 019. Рисуем треугольник в Qt5. Позиционирование в QGraphicsScene Евгений, здравствуйте! Решил поэкспериментировать немного с кодом из этого урока, нарисовать вместо треугольника квадрат и разобраться с координатами. В итоге, запутался. И ни документация,…
Evgenii Legotckoi
Evgenii Legotckoi25 мая 2023 г. 4:49
Как написать игру на Qt - Урок 2. Анимация героя игры (2D) Код на строчка 184-198 вызывает перерисовку области на каждый 4-й такт счётчика. По той логике не нужно перерисовывать объект постоянно, достаточно реже, чем выполняется игровой слот. А слот вып…
J
JonnyJo21 мая 2023 г. 10:49
Как написать игру на Qt - Урок 2. Анимация героя игры (2D) Евгений, благодарю! Всё равно не совсем понимаю :( Если муха двигает ножками только при нажатии клавиш перемещение, то что, собственно, делает код со строк 184-198 в triangle.cpp? В этих строчка…
Evgenii Legotckoi
Evgenii Legotckoi21 мая 2023 г. 5:57
Как написать игру на Qt - Урок 2. Анимация героя игры (2D) Добрый день. slotGameTimer срабатывает по таймеру и при каждой сработке countForSteps увеличивается на 1, это не зависит от нажатия клавиш, нажатая клавиша лишь определяет положение ножек, котор…
Сейчас обсуждают на форуме
T
Twanger7 июня 2023 г. 11:12
Ошибка при выполнении триггерной функции (GreenPlum) Есть 3 таблицы fact_amount со структурой: CREATE TABLE fact_amount ( id serial4 NOT NULL, fdate date NULL, type_activity_id int4 NULL, status_id int4 NULL, CONSTRAINT fact…
AR
Alexander Ryabikov6 июня 2023 г. 13:35
Работа с QFileSystemModel Вопросик по теме QFileSystemModel в Linux. Он, как и положено, обновляется самостоятельно, если директория локальная. Но, вот, сетевая папка (у меня шара samba) не обновляется. Как её можно…
Evgenii Legotckoi
Evgenii Legotckoi16 апреля 2023 г. 4:07
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Да, это возможно. Но подобные вещи лучше запускать через celery. То есть drf принимает команду, и после этого регистрирует задачу в celery, котроый уже асинхронно всё это выполняет. В противном …
АБ
Алексей Бобров14 декабря 2021 г. 19:03
Sorting the added QML elements in the ListModel I am writing an alarm clock in QML, I am required to sort the alarms in ascending order (depending on the date or time (if there are several alarms on the same day). I've done the sorting …

Следите за нами в социальных сетях