使用jar命令更新特定目录中JAR内的文件

所以我一直在高低寻找答案,显然没有找到满意的答案。

问题是我想在JAR中更新JAR(或任何文件),但是文件位于文件夹结构中,我希望避免在JAR外部再现,以便我可以更新它。

例:

Foo.jar (root directory) / |->/folder1 | |->/folder2 | |->/foo | |-->/bar | |---->/baz | |------>file_to_update.jar 

所以,如果我想使用jar命令更新它,我将首先在JAR之外创建相同的文件夹结构然后执行

 jar -uf Foo.jar -C foo/bar/baz/file_to_update.jar 

但是我想避免创建这个文件夹结构,因为对于某些文件它可能非常深,而且因为我可能需要在容器JAR上更新所选文件,所以我不想创建具有特定结构的这么多文件夹所以jar命令可以更新它们。

换句话说,我想告诉jar命令使用特定源目录中的特定源文件更新特定目标目录中的特定目标文件。

就是这样的

 jar -uf Foo.jar -sourceFile /x/y/z/filetoupdate -destFile /a/b/c/filetoupdate 

(我知道这种语法不起作用,只是为了举例说明我的需要)。

可以这样做吗? 当jar命令找到匹配的东西时,我绝对需要模仿整个文件夹结构,因为我可能需要更新文件夹结构中100个文件夹深度的文件。 。 重现只是为了更新文件,这将过于复杂。

此外,我知道可以使用常规的ZIP实用程序,但是我在Linux中可用的那个实际上并没有更新文件,即使它说它已经完成(重新打开jar时,它的旧版本完好无损),现在我不能去寻找另一个(公司政策,没有时间,测试问题,你的名字)。

最后,如果我可以从命令行执行此操作,则意味着我可以创建批处理文件来更新大量特定文件,而无需创建文件夹结构。

我忘了说我也想避免不得不解开,更新,重新调整整个事情,因为这个JAR可以上升到2GB所以这需要一段时间来做到这一点,基本上,添加一点资源文件到我的巨大的JAR。

非常感谢任何帮助!

4129445:在Sun / Oracle错误数据库中逐步更新ZIP文件的API要求在java api中实现此function。

来自评估:

“很容易同情那些希望修复这个bug的人。也许更容易同情那些无意中覆盖已经被正在运行的JVM使用的JAR文件的人。”

“如果jar和zip API从第一天开始就允许使用可变的zip文件就好了。但是在这一点上,添加来自Java的jar和zip文件的可变性(或者更确切地说,增加改变它们的容易性)似乎可能会引入更难以调试的问题。“

正如已接受的答案已经指出的那样,您既不能使用zip也不能使用jar命令将文件系统上的特定文件插入压缩文件中的特定目录。

但是有这种解决方法 ,简而言之,首先在压缩文件中提取特定文件,您可以更新它,然后将其放回压缩文件中:

1.提取单个文件:
考虑一个包含以下内容的jar

 $ jar tvf foo.jar 0 Thu Jan 10 00:05:06 IST 2013 META-INF/ 68 Thu Jan 10 00:05:06 IST 2013 META-INF/MANIFEST.MF 0 Thu Jan 10 00:04:30 IST 2013 x/ 0 Thu Jan 10 00:07:36 IST 2013 x/b/ 9 Thu Jan 10 00:07:36 IST 2013 x/b/hello.txt 0 Thu Jan 10 00:04:30 IST 2013 x/a/ 

要仅提取hello.txt,您必须提供文件到提取的完全限定路径。 Jar也会创建适当的文件夹。

示例:

 $ jar xvf foo.jar x/b/hello.txt inflated: x/b/hello.txt $ tree x/ x └── b └── hello.txt 1 directory, 1 file 

2.更新单个文件

  1. 修改提取的文件
  2. 使用’u’标志更新jar。 提供展开的目录root和jar将更新其下的所有路径元素。

例:

 $ jar vfu foo.jar x/ adding: x/(in = 0) (out= 0)(stored 0%) adding: x/b/(in = 0) (out= 0)(stored 0%) adding: x/b/hello.txt(in = 23) (out= 11)(deflated 52%) 

3.我尝试过哪个版本的jar?

我在Fedora 17上使用了与JDK 7捆绑在一起的jar


我已经validation了这里提到的所有步骤。 希望这可以帮助。

前面的讨论显示了一些用于更新zip(或jar)文件的Java源代码。

我不完全清楚这是否会比使用jar -u更快,但至少你应该能够调整该代码,这样你就不必在磁盘上重新创建文件结构。

编辑: 这是关于’jar’实用程序的文档 – 您可以亲眼看到您正在寻找的特定行为,虽然它很有用,但并不存在。

我认为原因是命令行界面基本上是Unix / Linux’tar’命令的克隆。 当然,它生成zip格式,而不是tar。

编辑#2 – 我想到要将文件添加到zip中,您只需要从文件末尾删除中心目录,附加新条目,然后重新编写中心目录。 更新将是相同的,除了不是将条目添加到目录,您将更新现有的目录条目以指向新的zip条目。

在探索这种可能性时,我发现Java 7包含一个zip文件系统提供程序 ,看起来就像这样,并且可以构成您想要做的解决方案的基础。

我认为这是由于java.util.zip包中的类如何工作。 他们坐在溪流之上。

ZipFile类构建在ZipFileInputStream之上。 编写zipfiles是通过将ZipEntries逐个送入ZipOutputStream来完成的。

我假设jar可执行文件是建立在这些类之上的。

我也试图更新jar而不重复jar的jar外部的jar文件结构,并且由于某种原因, jar uf jarFileName -C …命令永远不会让我将文件复制到jar中的子目录。 然后我尝试使用ubuntu 14.04的内置存档管理器将文件剪切并粘贴到jar中(即右键单击jar文件并选择“使用存档管理器打开”然后将文件粘贴到jar的文件结构中的任何位置),它工作正常。 它不是一个cli解决方案,但它的工作原理。 希望这能节省一些时间。

它有效,但它不是你正在寻找的extact解决方案。

而不是手动创建文件夹结构,我要求提到整个路径,所以mkdir将创建文件夹和子目录too.hope这有助于….

 set /p Folder=where you want to move inside jar set /p File=Mention path of file to be moved set /p Jarfile=Where is your jar file mkdir %Folder% copy %File% %Folder% jar -uvf %Jarfile% %File% rd /s /q %Folder% rmdir %Folder%