Как предотвратить стирание файла при возникновении ошибки при записи в него? - PullRequest
1 голос
/ 07 мая 2020

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

Проблема в том, что я запускаю этот код:

FileOutputStream output = new FileOutputStream(file);
output.write(data.getBytes());
output.close();

И если возникает исключение IOException при попытке записи в файл, данные теряются (поскольку создание экземпляра FileOutputStream очищает файл). Есть ли лучший способ сделать это, чтобы при возникновении исключения IOException старые данные остались нетронутыми? Или эта ошибка возникает только тогда, когда файл доступен только для чтения, поэтому мне просто нужно проверить это?

Моя единственная «работа» - это сообщить пользователю об ошибке и дать указанному пользователю правильный данные, которые пользователь должен обновить вручную. Хотя это может сработать для разработчика, в этом случае может возникнуть множество проблем. Кроме того, в этом случае у пользователя нет разрешения на редактирование файла, поэтому "обходной путь" вообще не работает.

Извините, если кто-то еще спросил об этом. При поиске результата не нашел.

Заранее спасибо!

1 Ответ

1 голос
/ 07 мая 2020

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

Существует вероятность того, что переименование не удастся. Чтобы быть полностью защищенным от этого, ваши файлы могут быть названы в соответствии со временем их создания. Например, если ваш файл называется save.dat, вы можете добавить время, когда файл был сохранен (от System.currentTimeMillis()), в конец имени файла. Затем, независимо от того, что произойдет позже (включая невозможность удалить старый файл или переименовать новый), вы сможете восстановить самое последнее успешное сохранение. Я включил пример реализации ниже, который представляет время в виде шестнадцатеричного числа 16-di git с нулями, добавленного к расширению файла. Вместо этого файл с именем save.dat будет сохранен как save.dat00000171ed431353 или что-то подобное.

// name includes the file extension (i.e. "save.dat").
static File fileToSave(File directory, String name) {
    return new File(directory, name + String.format("%016x", System.currentTimeMillis()));
}

// return the entire array if you need older versions for which deletion failed. This could be useful for attempting to purge any unnecessary older versions for instance.
static File fileToLoad(File directory, String name) {
    File[] files = directory.listFiles((dir, n) -> n.startsWith(name));
    Arrays.sort(files, Comparator.comparingLong((File file) -> Long.parseLong(file.getName().substring(name.length()), 16)).reversed());
    return files[0];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...