2010-07-21 49 views
2

我的Java应用程序目前使用ZIP作为项目文件格式。该项目文件包含一些XML文件和许多图像和声音文件。替代ZIP作为项目文件格式。 SQLite或其他?

项目文件变得非常大,因为我找不到用java.util.zip类写入ZIP文件而不重新创建它的方法,所以我的文件保存变得非常缓慢。例如,如果我只想更新一个XML文件,我需要重写整个ZIP。

是否有一些其他的Java ZIP库,允许我随机写入ZIP文件?

我知道切换到像SQLite这样的东西可以解决随机写入问题。使用SQLite只是将XML,声音和图像编写为blob是否合适?

我想我可以想出我自己的文件格式并使用RandomAccessFile,但随后会有很多簿记我不得不写。

更新...

我的文件格式是很像Office Open XML。它是一个包含XML和其他资源的ZIP文件。

有人必须解决如何做随机写入更新ZIP文件的问题。有谁知道如何?

+1

“我的Java应用程序目前使用ZIP作为项目文件格式。” < - JAR文件不会更有意义吗? – Powerlord 2010-07-21 17:04:15

+0

有没有办法随机写入与ZIP不同的JAR? – awinbra 2010-07-21 18:03:02

+1

JAR实际上是一个ZIP +元数据。在性能方面与ZIP没有区别。 – 2010-07-21 19:30:36

回答

2

存在所谓的单文件虚拟文件系统,它允许您创建基于文件的容器并提供文件系统结构和API。其中一个示例是SolFS(它具有使用JNI封装的C编写的核心)以及其他一些由C和Delphi编写的解决方案(我现在不记得他们的名字)。我猜也存在类似的本地Java解决方案。

+0

虚拟文件系统可能是一个很好的方向。 我发现TrueZip声称是用于ZIP的Java虚拟文件系统。如果它真的具有对ZIP文件的随机写入访问权,这将是一个完美的解决方案。将进一步调查。 – awinbra 2010-07-21 22:15:46

+0

我想我明白你的问题。 Java内置的ZIP类不支持修改现有的存档(即没有AddEntry/DeleteEntry方法),并且trueZip只是填补了这个空白(并且该差距特定于ZIP访问代码的特定实现)。 然而,这不是真正的虚拟文件系统,因为ZIP格式本身不打算在这种情况下使用。当ZIP文件被修改时,无论您使用什么样的库或组件,这仍然是一个漫长而耗时的操作。 待续... – 2010-07-22 09:05:47

+0

相反,“真正的”虚拟文件系统操作页面(如物理磁盘上的群集),添加和删除文件不需要重写文件(引擎盖下或显式)。只有修改过的页面会被原地覆盖。 使用TrueZip创建一个巨大的文件,并尝试删除或修改文件中间的条目并测量速度。 – 2010-07-22 09:07:08

2

首先,我会将您的应用程序的资源分离为静态(如图像)和那些可以更改(您提到的xml文件)的资源。 由于静态文件不会被重新编写,您可以继续将它们存储在一个zip文件中,恕我直言,这是一种很好的方法来部署任何资源。

现在你有两个选择:

  • 由于非静态文件可能不会太大(XML文件中都可能会比图片+声音小),您可以与您当前的解决方案棒(zip文件),并简单地维护2个zip文件,其中只有一个(带有可更改文件的小文件)可以/将被重写。

  • 您可以使用内存数据库(如hsqldb)来存储可更改的文件,并且只在应用程序关闭或该操作明确时才将其保留(从数据库传输到驱动器上的文件)需要。

+0

我需要在单个项目文件中包含所有内容。 – awinbra 2010-07-21 17:03:25

1

sqlite并不总是很快(至少在我的经验)。我会建议单独压缩XML文件 - 你仍然会得到体面的压缩,并且只是使用文件系统来保存它们。您可以尝试使用btrfs,或者使用ext4。如果你不在Linux上,那么它仍然可以正常工作,但是它可能不会那么快,直到事情被缓存在内存中。

的想法是,如果你没有冗余做之间的XML文件,那么你就没有在一个“实”档案压缩他们得到多储蓄。

+0

ZIP的目标不是压缩XML,而是将所有项目文件分组到一个文件中。我可以使用btrfs来做到这一点吗? – awinbra 2010-07-21 17:08:07

+0

不,对不起。我建议不要将文件分组。你为什么想这样做? 在Linux中,您可以使用任何常规文件作为整个文件系统 - 只需运行诸如“dd if =/dev/zero of = file1 bs = 1M count = 100; /sbin/mkfs.ext4 file1; mkdir -p你可以通过“md5sum file1; echo> mountpoint/asdf; sync; md5sum file1”来观察你写入“mountpoint /”目录的所有内容, – gatoatigrado 2010-07-21 18:15:28

+0

我忘了添加 - 通过.dmg,Mac对相同的功能有很好的支持。 – gatoatigrado 2010-07-21 18:17:49

1

在根据使用正确结构的JAR提供另一个答案之前,我必须问 - 为什么需要将项目封装在一个文件中?你如何将程序分发给用户运行?

+0

它是用户下载和安装的桌面应用程序。他们非常喜欢用户使用PowerPoint。他们创建包含媒体文件并共享这些项目的项目。 – awinbra 2010-07-21 22:10:32

1

如果你必须保持一个项目包含在一个文件中,并能够有效地替换资源,是的,我会说SQLite是一个不错的选择。

如果您确实选择使用SQLite,请考虑将某些XML模式转换为一个或多个SQL表,而不是将大型XML文档存储为BLOB。

相关问题