Вопрос

Статья Тима Брея «БЕЗОПАСНОЕ ДАННЫЕ» оставил мне открытые вопросы. Сегодня ему больше месяца, и я не видел никаких последующих последствий, поэтому я решил рассмотреть эту тему здесь.

Одна точка статьи заключается в том, что FileScriptor.sync () должен быть вызван, чтобы быть на безопасной стороне при использовании FileOutputStream. Сначала я был очень раздражен, потому что я никогда не видел кода Java, который делал синхронизацию в течение 12 лет, когда я делаю Java. Тем более, что справиться с файлами - довольно простая вещь. Кроме того, стандартный Javadoc of FileOutputStream никогда не намекал на синхронизацию (Java 1.0 - 6). После некоторых исследований я решил, что EXT4 может быть первой основной файловой системой, требующей синхронизации. (Есть ли другие файловые системы, где рекомендуется явное синхронизацию?)

Я ценю некоторые общие мысли по этому поводу, но у меня также есть некоторые конкретные вопросы:

  1. Когда Android сделает синхронизацию в файловую систему? Это может быть периодически и дополнительно основано на событиях жизненного цикла (например, процесс приложения идет на задний план).
  2. Позаботится ли FileScriptor.sync (), чтобы синхронизировать метаданные? Это синхронизирует каталог измененного файла. Сравните с FileChannel.force ().
  3. Обычно, кто -то не пишет в FileOutputStream. Вот мое решение (вы согласны?):
    FileOutputStream fileOut = ctx.openFileOutput(file, Context.MODE_PRIVATE);
    BufferedOutputStream out = new BufferedOutputStream(fileOut);
    try {
        out.write(something);
        out.flush();
        fileOut.getFD().sync();
    } finally {
        out.close();
    }
    
Это было полезно?

Решение

Android сделает синхронизацию, когда это необходимо - например, когда экран выключает, выключение устройства и т. Д. Если вы просто смотрите на «нормальную» работу, явная синхронизация по приложениям никогда не требуется.

Проблема возникает, когда пользователь вытаскивает батарею из своего устройства (или делает жесткий сброс ядра), и вы хотите убедиться, что не теряете никаких данных.

Таким образом, первое, что можно понять: проблема в том, когда власть внезапно проиграна, поэтому чистое отключение не может произойти, и вопрос о том, что произойдет в постоянном хранении в этот момент.

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

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

Это часто делается путем написания данных в новом файле, а затем переключив их из старого файла. До ext4 вы знали, что, как только вы закончите написание файла, дальнейшие операции в других файлах не будут проходить диск до тех, что в этом файле вы могли бы безопасно удалить предыдущий файл или иным образом выполнять операции, которые зависят от вашего нового файла быть полностью написанным.

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

Другие советы

fileOut.getFD().sync(); Должен быть в предложении наконец, прежде чем close().

sync() гораздо важнее, чем close() Учитывая долговечность.

Итак, каждый раз, когда вы хотите «закончить», работая над файлом, вы должны sync() это раньше close()это.

POSIX не гарантирует, что ожидающие записи будут записаны на диск, когда вы выпустите close().

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top