2011-06-01 72 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代码)。

希望有所帮助。