2012-01-03 49 views
1

是否有可能將Java EE應用程序(基於Spring Framework,運行於Tomcat容器中)保存在服務器上的文件中?Java EE中安全的基於文件的數據持久性

的情況如下:我有與int字段的一類(在啓動過程中從讀?)。我想以安全的方式將它保存到文件中(儘可能安全,這意味着倖存的服務器崩潰將不勝感激)。是否有可能(除了天真的文件讀取/寫入)

親切的問候, q

回答

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

這裏發生的事情是第一次,我們正在寫的文件到一個臨時文件。這可確保整個文件寫入成功,而不會損壞原始文件(例如,如果磁盤空間不足,原始文件將保留,因爲此例程不會完成)。但是,如果此例程失敗,臨時存儲的臨時文件將保留,並且需要稍後清理。

一旦我們寫的文件中,我們強制操作系統刷新任何未決寫入實際的磁盤。許多系統將文件系統緩衝區寫入內存,並「最終」將它們寫入磁盤。這是顯而易見的性能原因。但是,如果系統在關閉文件之間崩潰或斷電,並且操作系統決定刷新寫入,則可能會丟失數據。這個同步是一個昂貴的操作。最後,一旦我們確定我們已經寫入了這個文件,並且它已經被提交到磁盤上了,那麼我們就會將臨時文件重命名爲實際的文件名。

重命名文件系統上的文件是一個原子操作。它不能部分失敗。它可以工作,也可以不工作。如果這兩個文件位於同一個文件系統中,則重命名是即時的,因爲它只是更新一些文件系統信息。如果兩者位於不同的文件系統上,則必須先將新文件複製到新文件系統,然後重新命名。我假設這是如何完成的,我從來沒有測試過。我傾向於堅持相同的文件系統並完全避免這個問題。

此過程確保文件將以正確的名稱完全更新爲「全部一次」。該文件(在其正確的名稱下)不僅僅「部分存在」,如果您只是簡單地覆蓋現有文件,會發生什麼情況。

最後,在Windows上,如果原始文件存在爭用,您可能會遇到問題,因爲Windows不會刪除由其他內容打開的文件。這樣做的Unix沒有問題,但Windows確實如此。因此,您需要通過一些外部手段確保您在執行此重命名過程之前可以唯一訪問該文件。

+0

這是一個答案!非常感謝你! – Queequeg 2012-01-05 07:16:52

0

這可能是矯枉過正上您的具體情況,但你可以使用HSQLDB。您可以將其配置爲保留在文件中。

對於更簡單的解決方案,您可以隨時寫入/讀取文件。值得考慮的一些問題:

  • 使用JNDI或系統變量來存儲文件的名稱和路徑。
  • 確保運行服務器的用戶具有對該文件的讀/寫訪問權限。
  • 以外,你可以使用標準的Java文件操作
0

您可以使用Java中serializable界面來創建可以保存和從盤重裝持久對象。

+0

當然,我知道這一點。但我必須手動調用序列化方法。我想要它自己保存或smt。 simmilar。我想在服務器崩潰等情況下倖存下來。 – Queequeg 2012-01-03 14:50:01

+1

我在我的對象中實現了serializable,然後在啓動服務器時讀取了序列化對象,並將它們寫入狀態更改。我的要求是在戰爭文件的崩潰和重新部署中倖存下來,所以我必須確保磁盤上的序列化對象與服務器的當前狀態一致。想想文件系統期刊是如何工作的,那就是你需要做的。 – 2012-01-03 15:15:41

+0

'寫出他們對狀態變化' - 你怎麼接受這樣的事件? – Queequeg 2012-01-05 07:13:48

1

簡短的回答是肯定的。我實際上不得不爲一個我剛剛在大學做過的項目做這件事。我在git集線器上發佈了它的代碼:Speak To Me project。在該Web應用程序中,我堅持將用戶數據以純文本格式保存起來,因此它既易於人類閱讀,又易於讓對象重新初始化自己。

所以這個問題的讀者可能會奇怪,爲什麼我沒有使用數據庫用於這些目的。那麼我與之合作的大學不想支持一個。此外,這款應用的流量非常低,它是測試搜索界面的研究原型,因此僅用於用戶研究。最後,由於應用程序的性質,堅持文件保持非常簡單。事實上,這些數據文件後來被用於後期研究分析。此外,它還爲不擅長編程的學生敞開了腳步(從未發生過)。

總之,我的建議是,如果你只是簡單的持久價值,那麼純文本將被罰款。如果您的數據具有任何複雜性,請使用JSON。 XML有點重量級,只有在你的應用程序很大時才應該使用,但在這種情況下,你不應該堅持文件。

+0

謝謝你的回答! – Queequeg 2012-01-05 07:12:45