34

だから私はこれに対する答えを探していましたが、明らかに満足のいく答えは見つかりませんでした。

問題は、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 

(この構文が機能しないことはわかっています。必要なものを例示するだけです)。

これはできますか?100フォルダーの深さのフォルダー構造内のファイルを更新する必要がある可能性があるため、 jarコマンドが一致するものを見つけることができたときに、フォルダー構造全体を完全に模倣する必要があるのは非常に奇妙なことです。 。これは、ファイルを更新するためだけに再現するには非常に複雑です。

また、通常のZIPユーティリティを使用できることは知っていますが、Linuxで使用できるユーティリティは、ファイルを更新したと表示されていても更新されていません(jarを再度開くと、古いバージョンはそのままです)。私は別のものを探しに行くことができません(会社の方針、時間なし、テストの問題、あなたはそれに名前を付けます)。

最後に、コマンドラインからこれを実行できる場合は、フォルダー構造を作成しなくても、バッチファイルを作成して多くの特定のファイルを更新できることを意味します。

このJARは2GBまで増加する可能性があるため、基本的に小さなリソースファイルを追加するためだけにこれを行うには時間がかかるため、全体を解凍、更新、再jarする必要も避けたいと言うのを忘れました。巨大なJAR。

これに関するどんな助けも大歓迎です!

4

6 に答える 6

53

受け入れられた回答がすでに指摘しているように、ファイルシステム上の特定のファイルを圧縮ファイル内の特定のディレクトリに挿入するためにzipnorもコマンドも使用できません。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を更新します。展開されたディレクトリのルートを指定すると、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のバージョンはどれですか?

jarFedora17でJDK7にバンドルされているものを使用しました。


ここに記載されているすべての手順を確認しました。お役に立てれば。

于 2013-01-09T19:03:36.220 に答える
4

4129445: Sun / OracleバグデータベースのZIPファイルを段階的に更新するAPIは、この機能をJavaAPIに実装するように要求します。

評価から:

「このバグを修正したい人には共感しやすい。実行中のJVMですでに使用されているJARファイルを誤って上書きしてしまった人には共感しやすいだろう。」

「jar&zip APIが最初から変更可能なzipファイルを許可していれば良かったでしょう。しかし、この時点で、Javaからjar&zipファイルに変更可能性を追加する(というより、変更のしやすさを向上させる)と、よりデバッグが難しい問題。」

于 2013-01-13T20:43:53.410 に答える
1

この前の説明は、zip(またはjar)ファイルを更新するためのJavaソースコードを示しています。

これが実際に使用するよりも高速であるかどうかは私には完全にはわかりませんjar -uが、少なくとも、ディスク上にファイル構造を再作成する必要がないように、そのコードを適応させることができるはずです。

編集:これが「jar」ユーティリティに関するドキュメントです。探している特定の動作は便利ですが、そこにはないことがわかります。

その理由は、コマンドラインインターフェイスが基本的にUnix/Linuxの「tar」コマンドのクローンであるためだと思います。もちろん、tarではなくzip形式を生成します。

編集#2-ファイルをzipに追加するには、ファイルの末尾から中央ディレクトリを削除し、新しいエントリを追加してから、中央ディレクトリを書き直す必要があることに気付きました。更新は同じことですが、ディレクトリにエントリを追加する代わりに、既存のディレクトリエントリを更新して、新しいzipエントリを指すようにします。

この可能性を調査していると、Java 7には、これを実行しているように見えるzipファイルシステムプロバイダーが含まれており、実行したいことのソリューションの基礎を形成できることがわかりました。

于 2013-01-09T03:23:40.637 に答える
1

これは、java.util.zipパッケージのクラスがどのように機能するかによるものだと思います。彼らは小川の上に座っています。

ZipFileクラスは、ZipFileInputStreamの上に構築されます。zipファイルの書き込みは、ZipEntriesを1つずつZipOutputStreamにフィードすることによって行われます。

jar実行可能ファイルはこれらのクラスの上に構築されていると思います。

于 2013-01-13T19:54:23.013 に答える
0

私もjarの外部でjarのファイル構造を再現せずにjarを更新しようとしていましたが、何らかの理由でjar uf jarFileName-C...コマンドでファイルをjarの子ディレクトリにコピーできませんでした。次に、ubuntu 14.04に組み込まれているアーカイブマネージャーを使用してファイルを切り取ってjarに貼り付けてみました(つまり、jarファイルを右クリックし、[アーカイブマネージャーで開く]を選択して、jarのファイル構造内の任意の場所にファイルを貼り付けます)。 。これはCLIソリューションではありませんが、機能します。これが他の誰かの時間を節約することを願っています。

于 2016-09-08T14:35:35.850 に答える
-2

それは機能しますが、あなたが見ている正確な解決策ではありません。

フォルダ構造を手動で作成する代わりに、パス全体について言及するように求めているので、mkdirはフォルダとサブディレクトリも作成します。これがお役に立てば幸いです。

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%
于 2017-07-20T06:04:06.647 に答える