В этом уроке:

- работаем с файлами

 

Работа с файлами в Android не сильно отличается от таковой в Java. В этом уроке рассмотрим, как записать/прочесть файл во внутреннюю память и на SD-карту.

 

Создадим проект:

Project name: P0751_Files
Build Target: Android 2.3.3
Application name: Files
Package name: ru.startandroid.develop.p0751files
Create Activity: MainActivity

 

Заполним strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">P0751_Files</string>
    <string name="write_file">Записать файл</string>
    <string name="read_file">Прочесть файл</string>
    <string name="write_file_sd">Записать файл на SD</string>
    <string name="read_file_sd">Прочесть файл с SD</string>
</resources>

 

Рисуем экран main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/btnWrite"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/write_file"
            android:onClick="onclick">
        </Button>
        <Button
            android:id="@+id/btnRead"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/read_file"
            android:onClick="onclick">
        </Button>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/btnWriteSD"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/write_file_sd"
            android:onClick="onclick">
        </Button>
        <Button
            android:id="@+id/btnReadSD"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/read_file_sd"
            android:onClick="onclick">
        </Button>
    </LinearLayout>
</LinearLayout>

4 кнопки, смысл которых понятен по тексту на них.

 

MainActivity.java:

package ru.startandroid.develop.p0751files;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;

public class MainActivity extends Activity {

  final String LOG_TAG = "myLogs";

  final String FILENAME = "file";

  final String DIR_SD = "MyFiles";
  final String FILENAME_SD = "fileSD";

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
  }

  public void onclick(View v) {
    switch (v.getId()) {
    case R.id.btnWrite:
      writeFile();
      break;
    case R.id.btnRead:
      readFile();
      break;
    case R.id.btnWriteSD:
      writeFileSD();
      break;
    case R.id.btnReadSD:
      readFileSD();
      break;
    }
  }

  void writeFile() {
    try {
      // отрываем поток для записи
      BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
          openFileOutput(FILENAME, MODE_PRIVATE)));
      // пишем данные
      bw.write("Содержимое файла");
      // закрываем поток
      bw.close();
      Log.d(LOG_TAG, "Файл записан");
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  void readFile() {
    try {
      // открываем поток для чтения
      BufferedReader br = new BufferedReader(new InputStreamReader(
          openFileInput(FILENAME)));
      String str = "";
      // читаем содержимое
      while ((str = br.readLine()) != null) {
        Log.d(LOG_TAG, str);
      }
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  void writeFileSD() {
    // проверяем доступность SD
    if (!Environment.getExternalStorageState().equals(
        Environment.MEDIA_MOUNTED)) {
      Log.d(LOG_TAG, "SD-карта не доступна: " + Environment.getExternalStorageState());
      return;
    }
    // получаем путь к SD
    File sdPath = Environment.getExternalStorageDirectory();
    // добавляем свой каталог к пути
    sdPath = new File(sdPath.getAbsolutePath() + "/" + DIR_SD);
    // создаем каталог
    sdPath.mkdirs();
    // формируем объект File, который содержит путь к файлу
    File sdFile = new File(sdPath, FILENAME_SD);
    try {
      // открываем поток для записи
      BufferedWriter bw = new BufferedWriter(new FileWriter(sdFile));
      // пишем данные
      bw.write("Содержимое файла на SD");
      // закрываем поток
      bw.close();
      Log.d(LOG_TAG, "Файл записан на SD: " + sdFile.getAbsolutePath());
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  void readFileSD() {
    // проверяем доступность SD
    if (!Environment.getExternalStorageState().equals(
        Environment.MEDIA_MOUNTED)) {
      Log.d(LOG_TAG, "SD-карта не доступна: " + Environment.getExternalStorageState());
      return;
    }
    // получаем путь к SD
    File sdPath = Environment.getExternalStorageDirectory();
    // добавляем свой каталог к пути
    sdPath = new File(sdPath.getAbsolutePath() + "/" + DIR_SD);
    // формируем объект File, который содержит путь к файлу
    File sdFile = new File(sdPath, FILENAME_SD);
    try {
      // открываем поток для чтения
      BufferedReader br = new BufferedReader(new FileReader(sdFile));
      String str = "";
      // читаем содержимое
      while ((str = br.readLine()) != null) {
        Log.d(LOG_TAG, str);
      }
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

В onclick обрабатываем нажатия 4-х кнопок и вызываем соответствующие методы.

writeFile – запись файла во внутреннюю память. Используется метод openFileOutput, который на вход берет имя файла и режим записи: MODE_PRIVATE – файл доступен только этому приложению, MODE_WORLD_READABLE – файл доступен для чтения всем, MODE_WORLD_WRITEABLE - файл доступен для записи всем, MODE_APPEND – файл будет дописан, а не начат заново.

readFile – чтение файла из внутренней памяти. Используем метод openFileInput, принимающий на вход имя файла. Здесь и в методе записи внутреннего файла вы можете задать только имя файла, а каталог для ваших файлов вам уже выделен.

writeFileSD – запись файла на SD. Используем метод getExternalStorageState для получения состояния SD-карты. Здесь можно посмотреть какие бывают состояния. Нам нужно MEDIA_MOUNTED – когда SD-карта вставлена и готова к работе. Далее мы получаем путь к SD-карте (метод getExternalStorageDirectory), добавляем свой каталог и имя файла, создаем каталог и пишем данные в файл.

readFileSD – чтение файла с SD. Все аналогично предыдущему методу, только файл не пишем, а читаем.

 

Осталось в манифест добавить разрешение на работу с файлами на SD - android.permission.WRITE_EXTERNAL_STORAGE.

 

Все сохраним и запустим. Видим экран с 4-мя кнопками:

 

Внутренняя память

Жмем кнопку Записать файл.  Видим в логе:

Файл записан

Проверим. Идем в File Explorer (Window > Show View > Other > Android > File Explorer) и открываем там папку data/data/ru.startandroid.develop.p0751files/files и видим там наш файл file.

Возвращаемся в эмулятор. Жмем Прочесть файл и в логе видим:

Содержимое файла

Это тот текст, который мы записывали в файл.

 

SD карта

Теперь жмем Записать файл на SD.

В логе видим:

Файл записан на SD: /mnt/sdcard/MyFiles/fileSD

Проверяем. Идем в FileExplorer и открываем там папку mnt/sdcard/MyFiles/ а в ней файл fileSD.

Возвращаемся в эмулятор и жмем кнопку Прочесть файл с SD. В логе видим:

Содержимое файла на SD

Этот текст мы и записывали.

 

mnt/sdcard - обычно этот путь ведет к содержимому SD-карты. Возможно у вас он будет другой.

 

 

В общем, при работе с файлами на SD вы используете стандартные java механизмы. А при работе с внутренним хранилищем для удобства можно использовать методы-оболочки от Activity:

openFileOutput – открыть файл на запись

openFileInput – открыть файл на чтение

deleteFile – удалить файл

И есть метод getFilesDir – возвращает объект File, соответствующий каталогу для файлов вашей программы. Используйте его, чтобы работать напрямую, без методов-оболочек.

 

Подробности работы в java с файловой системой я здесь описывать не буду. На нашем форуме пользователь SKR сделал отличную памятку по работе с файлами. Скорее всего, вы найдете там все что нужно.

Если у вас проверка SD-карты показывает, что карта недоступна (см. лог), то убедитесь в свойствах AVD, что у вас для SDCard указан Size или File. Если указаны, то попробуйте перезапустить AVD.

 

На следующем уроке:

- создаем экран с вкладками
- используем иконку в названии вкладки
- используем обработчик перехода между вкладками


Присоединяйтесь к нам в Telegram:

- в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

- в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Compose, Kotlin, RxJava, Dagger, Тестирование, Performance 

- ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня




Language

Автор сайта

Дмитрий Виноградов

Подробнее можно посмотреть или почитать.

Никакие другие люди не имеют к этому сайту никакого отношения и просто занимаются плагиатом.

Социальные сети

 

В канале я публикую ссылки на интересные и полезные статьи по Android

В чате можно обсудить вопросы и проблемы, возникающие при разработке



Группа ВКонтакте



Поддержка проекта

Яндекс
410011180491924

WebMoney
R248743991365
Z551306702056

Paypal