私は瓶や戦争をしています。Jarファイル内のa * .jarファイルまたはファイルへの入力ストリーム?
私はプログラム的にこのジャーを読んでいます。このジャーの中にジャーを見つけたら、プログラムで読んでみたいと思います。
しかし、JarFileはgetInputStreamのみを提供しています。これはJarFile(Fileファイル)コンストラクタに渡すことはできません。
瓶から瓶を読み取る方法は?
EDIT:私はファイルを何とかクラスローダーから取得することを考えていました。
私は瓶や戦争をしています。Jarファイル内のa * .jarファイルまたはファイルへの入力ストリーム?
私はプログラム的にこのジャーを読んでいます。このジャーの中にジャーを見つけたら、プログラムで読んでみたいと思います。
しかし、JarFileはgetInputStreamのみを提供しています。これはJarFile(Fileファイル)コンストラクタに渡すことはできません。
瓶から瓶を読み取る方法は?
EDIT:私はファイルを何とかクラスローダーから取得することを考えていました。
あなたは、ファイルシステム内のjarファイル、
File tempFile=TempFile.createFile("newJar",".jar");
のようなものを作成してそこにストリームを書き込むことができます。その後、あなたは...プログラムは、符号なしのアプレット/ JNLPを実行している場合は、ファイルシステム内のファイルを作成する権限を持っていないので
それについて忘れて...あなたのするJarFile(一時ファイル)を構築し、それを扱うことができる
更新:申し訳ありませんが、これはあなたのニーズには遅すぎる可能性がありますが、私はちょうどコメントであなたの最後の質問を見つけました。そこで、外側のジャーを膨らませる必要なく、ネストされた各エントリがOutputStream
に直接コピーされていることを示すようにこの例を変更しました。
この場合、OutputStream
はSystem.out
ですが、任意のOutputStream
(たとえば、ファイル...など)でもかまいません。
一時ファイルを使用する必要はありません。 JarFile
の代わりにJarInputStream
を使用し、外部エントリのInputStream
をコンストラクタに渡すと、jarの内容を読み取ることができます。例えば
:
JarFile jarFile = new JarFile(warFile);
Enumeration entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry jarEntry = (JarEntry) entries.nextElement();
if (jarEntry.getName().endsWith(".jar")) {
JarInputStream jarIS = new JarInputStream(jarFile
.getInputStream(jarEntry));
// iterate the entries, copying the contents of each nested file
// to the OutputStream
JarEntry innerEntry = jarIS.getNextJarEntry();
OutputStream out = System.out;
while (innerEntry != null) {
copyStream(jarIS, out, innerEntry);
innerEntry = jarIS.getNextJarEntry();
}
}
}
...
/**
* Read all the bytes for the current entry from the input to the output.
*/
private void copyStream(InputStream in, OutputStream out, JarEntry entry)
throws IOException {
byte[] buffer = new byte[1024 * 4];
long count = 0;
int n = 0;
long size = entry.getSize();
while (-1 != (n = in.read(buffer)) && count < size) {
out.write(buffer, 0, n);
count += n;
}
}
JarEntryをZipFileとして処理できないと思います。エントリー()を取得して作業してください。 – blefesd
試してみてください。瓶は、異なる拡張子とそれがマニフェストを持つ慣習を持つ単なるジッパーです。 –
しかし、JarEntryまたはZipEntryから、あなたは含まれているjarのすべてのエントリを取得することはできません。このように:JarFile jf = new JarFile(jarName); 列挙型
再帰的に新しいjarファイルを読むためにもう一度するJarFileを使用します。例の場合、
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
public class JarReader {
public static void readJar(String jarName) throws IOException {
String dir = new File(jarName).getParent();
JarFile jf = new JarFile(jarName);
Enumeration<JarEntry> en = jf.entries();
while(en.hasMoreElements()) {
ZipEntry ze = (ZipEntry)en.nextElement();
if(ze.getName().endsWith(".jar")) {
readJar(dir + System.getProperty("file.separator") + ze.getName());
} else {
InputStream is = jf.getInputStream(ze);
// ... read from input stream
is.close();
System.out.println("Processed class: " + ze.getName());
}
}
}
public static void main(String[] args) throws IOException {
readJar(args[0]);
}
}
これは動作しません。JarFile jf = new JarFile(jarName); JarFileは、システム上のjarName(ファイル)を想定しています。 そして、あなたはjava.util.zip.ZipExceptionを取得します:システムが指定されたパスを見つけることができません – blefesd
一般的には、InputStreamに到達してから作業してください。これにより、ほとんどの「jar in jar in web server」の問題などを抽象化することができます。
この場合は、明らかにJarFile.getInputStream()とJarInputStream()です。
あなたに何も止まることはありませんが、瓶には他の瓶が入ってはいけません。私はあなたが達成しようとしている機能を実装する別の方法を探します。 http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html –
これはwarファイル内にあります。 – blefesd
@Nick Eclipseプラグインは反例です。それらはjarファイルとして配信され、しばしば入れ子になったjarを含んでいます。 –