2011-06-01 106 views
1

我正在創建一個需要大量圖像縮略圖(〜3000,5-25KB)的應用程序。由於速度至關重要,我計劃在應用程序啓動時將這些圖像加載到內存中。在運行時,新的縮略圖將被下載並添加到集體中。存儲大量小文件:存檔與文件系統

我可以將它們全部存儲在一個文件夾中,但在程序啓動時將數千個文件讀入內存似乎效率不高。

我的第二個選擇是將它們保存在某種(壓縮)存檔中。這會使存儲本身和加載更有效率(我認爲)。但是,新文件將定期添加,這可能不會像將文件保存在文件夾中那樣流暢。

正在(壓縮)存檔中存儲小文件的緩存是不是一個壞主意? ZIP文件是要走的路嗎?使用未壓縮的檔案(如果是,請問是什麼類型)我會更好嗎?

所有圖像文件將是JPEG的。

在此先感謝!

編輯:我正在考慮放棄「在應用程序啓動時將所有內容加載到內存」的事情。這會簡化我的問題。我最初的想法是將所有內容放在一個大文件中,這似乎不太有利,因爲一個目錄中的許多文件的問題可以通過散列到子目錄中來解決。

+0

壓縮在壓縮圖像文件格式上效果很差(圖像格式已經比通用壓縮算法可以管理的更好。你可能會用'.tar'來減少開銷。 – 2011-06-01 16:54:43

回答

1

小文件不壓縮得特別好,所以你可能不會獲得太多壓縮。

加載文件時會很快,因爲它們較小,解壓縮會增加時間。你必須試驗看哪個更快。

我認爲真正的問題會涉及到迭代所有小文件時文件系統的效率,尤其是如果它們都在一個文件夾中。當文件夾包含大量文件時,Windows在效率方面非常低效而臭名昭着。

我會考慮做一些事情,比如將它們寫入一個未壓縮的文件,這些文件可能會流入內存 - 可能不一定是連續的內存,因爲這可能是一個問題。但是這個想法是把它們放在一個文件中。然後編寫某種索引,將文件名或其他標識符與可以確定內存中圖像位置的偏移量綁定。

可以在最後添加新圖像,並適當更新索引。

這不是花哨的,但這就是你想要避免的。檔案,甚至文件系統爲您提供了大量的功能和靈活性,但是以犧牲效率爲代價。當你知道你想要做什麼時,有時候簡單會更好。

我會考慮實施一個解決方案,從一個文件夾中讀取文件,另一個將文件分割成子文件夾和子文件夾,以便在任何給定文件夾中不超過100個左右的文件,然後計時這些解決方案,相比於。我會認爲一個簡單的索引文件會足夠快,以至於甚至不需要像預先建議的那樣預先加載圖像 - 只需在需要時檢索它們,並在內存中保留它們。

+0

這正是我想到的那種容器存儲!現在我已決定在程序啓動時將所有內容加載到內存中,這取決於以下選擇:一個大型索引文件或將圖像保存在散列分佈的子文件夾中。單獨的文件似乎更容易實現,但我願意對兩個選項進行基準測試。你知道任何支持你正在描述的未壓縮歸檔的Java庫嗎?或者這是我必須創造自己的東西? – Rapsey 2011-06-01 17:15:10

+0

未壓縮的存檔===>您可以使用不壓縮數據的ZipOutputStream – ignis 2011-06-01 17:41:29

+0

http://download.oracle.com/javase/1.5.0/docs/api/java/util/zip/ZipOutputStream.html – ignis 2011-06-01 17:41:47

0

在我看來,我認爲壓縮文件的方式是一個壞主意,因爲你會放慢一切與加載壓縮文件並解壓縮提取每個圖像的過程。

我認爲縮略圖圖像的目的是本質上很小,因此您的應用程序和硬件可以儘可能快地加載它。所以我相信,根據需要加載每個圖像是一個更好的主意。

+0

是的,你是對的,壓縮JPEG的確聽起來相當愚蠢。我創建了縮略圖系統,因爲緩存中的所有圖像都是從服務器下載的。不知何故,下載幾千個1到5兆字節的文件似乎是一個壞主意。但是,如果我只是從硬盤上將它們加載,它可能確實是最好的。 非常感謝! – Rapsey 2011-06-01 17:18:52

1

所有基於磁盤的存儲和大多數數據庫都以塊的形式分配空間。大容量磁盤上的塊可能很大。如果你有5kb的文件和一個32kb的磁盤塊,你最終會在你的存儲上浪費85%的空間。

使用歸檔文件不會壓縮jpeg,因爲jpeg編碼算法已經做到了這一點。但是,它會爲您節省存儲介質上的浪費空間。它確實使事情更加複雜,可能會慢一點。

+0

謝謝,我甚至沒有想到!該應用程序通常在4KB塊大小的系統上運行,因爲無論如何,我們只討論幾千個文件,文件系統開銷不應超過幾兆字節。現在它可以簡單地將所有文件存儲在磁盤上或放入一個未壓縮的容器中。 謝謝! – Rapsey 2011-06-01 17:06:17

0

那麼,如果你有小的「幾何」圖片,你可以實現它們作爲javax.swing.Icon類型的對象,而不是從文件系統加載的圖像。 http://download.oracle.com/javase/6/docs/api/javax/swing/Icon.html

http://download.oracle.com/javase/tutorial/uiswing/components/icon.html

所以你要實現其自己繪製到使用圖形繪製圖元一個圖形表面的一個或多個對象,而不是複製像素。

+0

不幸的是,大多數圖像都是照片般的。這就是我爲什麼選擇JPEG的原因。不管怎麼說,還是要謝謝你! – Rapsey 2011-06-01 17:10:27

0

如果這是一個Web應用程序,那麼您可以獲得的最佳性能提升是設置良好的HTTP緩存標頭。每個圖像都有一個唯一的URL(也是同一圖像不同版本的不同URL),因此可以設置將來過期的標題,因爲更改圖像會更改導入重新提取的URL。

我不會壓縮,因爲JPEG不能很好地壓縮,並且只花費CPU時間。

我會推薦將圖像簡單地存儲到文件系統中,並考慮使用類似jawr的庫或實現您自己的緩存策略。

+0

這不是一個網絡應用程序,對不起,我應該提到這一點。但是我不知道jawr的存在。我相信這將在未來對我有用。 謝謝! – Rapsey 2011-06-01 17:07:56

0

我知道這個問題已經回答,但我認爲你需要更多的選擇,而不是壓縮。

雖然zip是好的,但由於JPEG已經壓縮,所以對JPEG沒有多大影響。

你可能要考慮其他的事情是:

  1. 把圖像中內容分發網絡(CDN)
  2. 用gzip壓縮組件(意味着服務器將自動壓縮每個響應),你以後不需要編寫任何代碼來解壓縮它 - 它會自動由瀏覽器處理。
  3. 由於您提到JPEG,因此您可能需要使用JPEGTran。對所有JPEG文件運行jpegtran。

    該工具可以進行無損的JPEG操作,如旋轉,也可用於優化和刪除圖像中的註釋和其他無用信息(如EXIF信息)。 jpegtran -copy none -optimize -perfect src.jpg dest.jpg

  4. 使用圖片精靈。而不是要求瀏覽器同時下載多個圖像,請讓瀏覽器只下載一個。

有關詳情如下:http://developer.yahoo.com/performance/rules.html#opt_images

對於基本的考試如何提高你的網站的性能,你可以嘗試安裝的YSlow的Firefox(插件檢測uneffecient代碼)。

希望有所幫助。