我有一個Java
項目,其中包含大量XML文件(> 500)。在運行時讀取這些文件會導致性能問題。從內存而不是磁盤讀取文件
是否有一個選項可以將所有XML文件加載到RAM中並從那裏讀取而不是從磁盤讀取?
我知道有像RamDisk這樣的產品,但這是一個商業工具。
我可以使用任何現有的Java API /庫將XML文件複製到主內存並從主內存中讀取嗎?
我有一個Java
項目,其中包含大量XML文件(> 500)。在運行時讀取這些文件會導致性能問題。從內存而不是磁盤讀取文件
是否有一個選項可以將所有XML文件加載到RAM中並從那裏讀取而不是從磁盤讀取?
我知道有像RamDisk這樣的產品,但這是一個商業工具。
我可以使用任何現有的Java API /庫將XML文件複製到主內存並從主內存中讀取嗎?
您是否考慮過爲這些文件創建對象結構並對它們進行序列化,java對象的序列化和反序列化比解析XML要快得多,這再次考慮到這500個左右的XML文件在讀取之間不會被修改。
here is an article談論序列化和反序列化。
如果關注的是加載文件內容到內存中,然後再考慮ByteArrayInputStream
,ByteArrayOutputStream
類甚至使用ByteBuffer
,這些都可以存儲在內存中的字節
Java對象序列化/反序列化並不比XML寫作和解析速度更快一般來說。當涉及大量對象時,Java序列化/反序列化實際上可能效率很低,因爲它跟蹤每個單獨的對象(因此重複的引用不會多次序列化)。這對於對象網絡來說很好,但對於簡單的樹結構來說,它增加了很多開銷而沒有增益。
您的最佳方法可能是使用快速技術處理XML(例如javax.xml.stream.XMLStreamReader
)。除非文件很大,否則加載XML文件的時間爲30-40秒是不符合要求的 - 您可能使用低效的方法來處理XML,例如將它們加載到DOM中。您也可以嘗試並行讀取多個文件(例如使用Java 8並行流)。
丹尼斯,我正在閱讀大量的文件在一個單一的行動,大約需要30-40秒。延遲不在處理xml文件中。我期望通過在啓動時將所有XML加載到RAM並從RAM中讀取它們來減少磁盤讀取時間。 –
你確定這個延遲真的是由磁盤訪問時間引起的嗎?您可以通過對虛擬硬盤驅動器中的文件運行測試來驗證此情況。如果磁盤訪問時間是問題,則虛擬磁盤是提高速度的最佳方式。如果一個ramdisk真的沒有生產的問題,那麼最好的辦法就是把所有的文件放到一個zip或gzip文件中,然後從中讀取單個文件。這種方法至少可以避免單獨訪問所有文件的一些開銷。 –
我會首先嚐試使用標準java庫中的RandomAccessFile
和FileChannel
提供的內存映射文件。通過這種方式,操作系統將能夠將常用的文件內容保存在內存中,從而有效地實現您想要的內容。
使用java.io.RandomAccessFile
類。它表現得像存儲在文件系統中的大量字節。此類的實例支持讀取和寫入隨機訪問文件。 另外我會建議使用MemoryMappedFile
,直接從磁盤讀取文件,而不是將其加載到內存中。
RandomAccessFile file = new RandomAccessFile("wiki.txt", "r");
FileChannel channel = file.getChannel();
MappedByteBuffer buf = channel.map(FileChannel.MapMode.READ_WRITE, 0, 1024*50);
然後你可以照常讀取緩衝區。
RandomAccessFile的行爲不像字節數組。 – EJP
https://docs.oracle.com/javase/7/docs/api/java/io/RandomAccessFile.html –
文檔說明 –
看起來像你的主要問題是大量的文件和內存不是問題。你可否確認?
是否有可能在預處理步驟中使用某種分隔符附加所有這些文件並創建一個大文件?通過這種方式,您可以增加讀取的塊大小,並避免磁盤搜索的性能損失。
您是否想過壓縮XML文件並讀取這些壓縮的XML文件?壓縮的XML可能只有原始大小的3-5%或更好。用戶可以看到它,然後再次將其壓縮存儲以便進一步閱讀。
這裏是一個圖書館,我發現可能會幫助: zip4j
這一切都取決於你是否多次讀取或不是數據更多。
假設我們使用某種基於Java的RamDisk(它實際上是某種緩衝區或字節數組)。
進一步假定處理數據的時間少於讀數。所以你必須至少閱讀一次。所以如果你先從磁盤到內存讀取它,然後從內存中處理它,那麼它就沒有區別。
如果您不止一次讀取文件,您可以將所有文件讀入內存(各種選項,緩衝區,字節陣列,自定義文件系統等)。
如果處理花費的時間比讀取的時間長(這似乎不是這種情況),您可以使用單獨的線程從磁盤預取文件 - 並使用另一個線程處理內存中的數據。
可以使用內存數據庫存儲中間文件(XML文件)。這會讓ram和db一起使用的速度。
僅供參考使用以下鏈接:
H2的用法作爲內存數據庫:
http://www.javatips.net/blog/2014/07/h2-in-memory-database-example
爲什麼不只是存儲數據在一個數據庫中緩存。 –
它是一個原始的XML文件,用戶經常在這裏編輯這些XML文件。將其存儲在數據庫中我有兩個選項1)存儲原始XML(對於頻繁編輯而言效率低)。 2)將XML數據轉換爲耗時的表格 –
用戶來自不同的場景。讓我們不要偏離到App類型。讓我們看看我們是否可以提出一些解決方案 –