2012-01-03 2 views
1

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

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

Уважения, д

ответ

2

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

Просто:

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); 
} 

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

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

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

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

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

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

+0

Этот адский ответ! Большое спасибо! – Queequeg

0

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

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

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

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

+0

Конечно, я знаю это. Но я должен вызвать метод сериализации вручную. Я хочу, чтобы он спасал себя или smt. simmilar. Я хочу, чтобы выжить при сбое сервера и т. Д. – Queequeg

+1

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

+0

'написал их о государственных изменениях' - как вы поймали такое событие? – Queequeg

1

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

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

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

+0

Спасибо за ваш ответ! – Queequeg

Смежные вопросы