Безопасное сохранение данных на основе файлов в Java EE - PullRequest
1 голос
/ 03 января 2012

Можно ли иметь приложение Java EE (на основе Spring Framework, работающее в контейнере Tomcat), сохраняющее свои данные в файле на сервере?

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

С уважением, д

Ответы [ 4 ]

2 голосов
/ 03 января 2012

Действительно, единственный «безопасный» способ сделать это - положиться на базовую файловую систему.

Просто:

public void saveThing(Serializable thing, String fileName) throws Exception {
    String tempFileName = fileName + "_tmp";
    File tempFile = new File(tempFileName);
    FileOutputStream fos = new FileOutputStream(tempFile);        
    FileDescriptor fd = fos.getFD();
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeObject(thing);
    oos.flush();
    fd.sync();
    oos.close();
    f.renameTo(fileName);
}

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

После того, как мы записали файл, мы заставим ОС сбросить все ожидающие записи на фактический диск.Многие системы буферной файловой системы записывают в оперативную память и «в конечном итоге» записывают их на диск.Это по очевидным причинам производительности.Тем не менее, в случае сбоя системы или потери питания между моментом, когда вы закроете файл, и ОС решит сбросить записи, вы можете потерять данные.Эта синхронизация является ДОРОГОЙ операцией.

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

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

Этот процесс гарантирует, что файл будет обновлен, с правильным именем, полностью, "все сразу".Файл (с его правильным именем) никогда не «частично существует», что происходит, если бы вы просто перезаписали существующий файл.

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

1 голос
/ 03 января 2012

Краткий ответ - да.Я действительно должен был сделать это для проекта, который я сделал с университетом некоторое время назад.Я разместил код для этого на своем git hub: Проект Speak To Me .В этом веб-приложении я сохранял пользовательские данные в файле в виде обычного текста, чтобы объекты могли быть удобочитаемыми и легкими для повторной инициализации объектов.

Так что читателям этого вопроса может быть интересно, почему я не использовалБаза данных для этих целей.Ну, университет, с которым я работал, не хотел его поддерживать.Кроме того, у этого приложения был действительно низкий трафик;это исследовательский прототип для тестирования поисковых интерфейсов, поэтому он использовался только для пользовательских исследований.Наконец, из-за характера приложения, сохранение в файле делает вещи действительно простыми.Фактически, файлы данных были позже использованы для анализа после исследования.Кроме того, он оставлял открытой возможность для студентов, которые не были хорошими программистами, чтобы промочить ноги (этого ... никогда не было).

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

0 голосов
/ 03 января 2012

Вы можете использовать serializable интерфейс в Java для создания постоянных объектов, которые вы можете сохранить и перезагрузить с диска.

0 голосов
/ 03 января 2012

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

Для более простого решения вы всегда можете писать / читать из файла.Некоторые вопросы, заслуживающие рассмотрения:

  • Используйте JNDI или системную переменную для хранения имени и пути к файлу.
  • Убедитесь, что пользователь, который запускает сервер, имеет права на чтение / записьдоступ к файлу.
  • Кроме этого вы можете использовать стандартные операции с Java-файлами
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...