Поиск…


Вступление

Чтение и запись файлов в Android не отличается от чтения и записи файлов в стандартной Java. Можно использовать тот же пакет java.io Тем не менее, есть некоторые особенности, связанные с папками, где вам разрешено писать, разрешения вообще и работа MTP.

замечания

Android предоставляет средства для обмена файлами между несколькими приложениями, как это описано здесь . Это не требуется, если есть только одно приложение, которое создает и использует файл.

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

Активность Android имеет несколько конкретных методов, которые выглядят как замена стандартных методов ввода файлов в формате Java. Например, вместо этого для File.delete() вы можете вызывать Context.deleteFile() , и вместо того, чтобы применять File.listFiles() рекурсивно, вы можете вызвать Context.fileList() чтобы получить список всех ваших конкретных файлов приложения несколько код. Однако они не обеспечивают дополнительную функциональность, кроме стандартного пакета java.io

Получение рабочей папки

Вы можете получить свою рабочую папку, вызвав метод getFilesDir() в своей деятельности (Activity - это основной класс вашего приложения, который наследуется от Context. См. Здесь ). Чтение не отличается. Доступ к этой папке будет иметь только ваше приложение.

Ваша деятельность может содержать следующий код, например:

  File myFolder = getFilesDir();
  File myFile = new File(myFolder, "myData.bin");

Написание исходного массива байтов

  File myFile = new File(getFilesDir(), "myData.bin");
  FileOutputStream out = new FileOutputStream(myFile);

  // Write four bytes one two three four:
  out.write(new byte [] { 1, 2, 3, 4}
  out.close()

В этом коде нет ничего особенного для Android. Если вы пишете много небольших значений, используйте BufferedOutputStream, чтобы уменьшить износ внутреннего SSD устройства.

Сериализация объекта

Старая хорошая сериализация объектов Java доступна для вас в Android. вы можете определить классы Serializable, например:

  class Cirle implements Serializable {
    final int radius;
    final String name;

    Circle(int radius, int name) {
      this.radius = radius;
      this.name = name;
    }
  }

а затем записать в ObjectOutputStream:

  File myFile = new File(getFilesDir(), "myObjects.bin");
  FileOutputStream out = new FileOutputStream(myFile);
  ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(out));

  oout.writeObject(new Circle(10, "One"));
  oout.writeObject(new Circle(12, "Two"));
  
  oout.close()

Сериализация объектов Java может быть либо идеальной, либо действительно плохим выбором, в зависимости от того, что вы хотите с ней сделать - вне рамок этого учебника и иногда основывается на мнениях. Прежде всего, ознакомьтесь с версией, если вы решите ее использовать.

Запись на внешнее хранилище (SD-карта)

Вы также можете читать и записывать с / на карту памяти (SD-карту), которая присутствует на многих устройствах Android. Доступ к файлам в этом месте могут получить другие программы, а также непосредственно пользователь после подключения устройства к ПК через USB-кабель и включения протокола MTP.

Поиск местоположения SD-карты несколько более проблематичен. Класс Environment содержит статические методы для получения «внешних каталогов», которые обычно должны находиться внутри SD-карты, а также информация, если SD-карта существует вообще и доступна для записи. Этот вопрос содержит ценные ответы, как убедиться, что правильное местоположение будет найдено.

Доступ к внешнему хранилищу требует разрешений в вашем проявлении Android:

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

Для более старых версий разрешения на размещение Android достаточно установить эти разрешения в манифест (пользователь должен утвердить во время установки). Однако начиная с Android 6.0 Android запрашивает у пользователя одобрение во время первого доступа, и вы должны поддержать этот новый подход. В противном случае доступ запрещается независимо от вашего манифеста.

В Android 6.0 сначала нужно проверить разрешение, а затем, если не предоставлено, запросите его. Примеры кода можно найти внутри этого вопроса SO .

Решение проблемы «Невидимые файлы MTP».

Если вы создаете файлы для экспорта через USB-кабель на рабочий стол с использованием протокола MTP, может возникнуть проблема, что вновь созданные файлы не будут сразу видны в проводнике файлов, работающем на подключенном настольном ПК. Чтобы сделать новые файлы видимыми, вам необходимо вызвать MediaScannerConnection :

File file = new File(Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_DOCUMENTS), "theDocument.txt");
FileOutputStream out = new FileOutputStream(file)

... (write the document)

out.close()
MediaScannerConnection.scanFile(this, new String[] {file.getPath()}, null, null);
    context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
            Uri.fromFile(file)));

Этот код вызова MediaScannerConnection работает только для файлов, а не для каталогов. Проблема описана в этом отчете об ошибке Android . Это может быть исправлено для некоторых версий в будущем или на некоторых устройствах.

Работа с большими файлами

Маленькие файлы обрабатываются за долю секунды, и вы можете читать / записывать их вместо кода, в котором это необходимо. Однако, если файл больше или медленнее обрабатывается, вам может потребоваться использовать AsyncTask в Android для работы с файлом в фоновом режиме:

    class FileOperation extends AsyncTask<String, Void, File> {

        @Override
        protected File doInBackground(String... params) {
          try {
            File file = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_DOCUMENTS), "bigAndComplexDocument.odf");
            FileOutputStream out = new FileOutputStream(file)

           ... (write the document)

            out.close()
            return file;
            } catch (IOException ex) {
               Log.e("Unable to write", ex);
               return null;
              }
        }

        @Override
        protected void onPostExecute(File result) {
          // This is called when we finish 
        }

        @Override
        protected void onPreExecute() {
           // This is called before we begin
        }

        @Override
        protected void onProgressUpdate(Void... values) {
            // Unlikely required for this example
        }
    }
}

а потом

new FileOperation().execute("Some parameters");    

Этот вопрос SO содержит полный пример создания и вызова AsyncTask. Также см. Вопрос об обработке ошибок о том, как обрабатывать IOExceptions и другие ошибки.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow