[〜#〜] jar [〜#〜] ファイルを作成しました。ここで、別のJavaプログラムを作成しました。そのJARファイルを他のディレクトリに解凍したい、つまり、unzipのようなことをしたいのです。
jar -xf filename.jar
を実行すると、エラーが発生します。
Exception in thread "main" Java.io.IOException: Cannot run program "jar":
Java.io.IOException: error=2, No such file or directory
at Java.lang.ProcessBuilder.start(ProcessBuilder.Java:459)
at Java.lang.Runtime.exec(Runtime.Java:593)`
この例を適用します。 抽出方法Java JARおよびZipアーカイブからのリソース
またはこのコードを試してください:
プログラムでZip/JARファイルの内容を抽出する
jarFile
が抽出されるjar/Zipファイルであるとします。destDir
は、抽出されるパスです。Java.util.jar.JarFile jar = new Java.util.jar.JarFile(jarFile); Java.util.Enumeration enumEntries = jar.entries(); while (enumEntries.hasMoreElements()) { Java.util.jar.JarEntry file = (Java.util.jar.JarEntry) enumEntries.nextElement(); Java.io.File f = new Java.io.File(destDir + Java.io.File.separator + file.getName()); if (file.isDirectory()) { // if its a directory, create it f.mkdir(); continue; } Java.io.InputStream is = jar.getInputStream(file); // get the input stream Java.io.FileOutputStream fos = new Java.io.FileOutputStream(f); while (is.available() > 0) { // write contents of 'is' to 'fos' fos.write(is.read()); } fos.close(); is.close(); } jar.close();
このコードスニペットを参照として使用して、タスクを完了できます。FileNotFoundExceptionを取得している人を除いて、上記の@JuanZeで示したコードスニペットとほぼ同じですが、ファイルが存在し、存在しない場合は、ファイルとともに親フォルダーを作成し、指定された宛先フォルダー内のjarファイルの内容を抽出します。
コードスニペット:
public class JarDemo {
public static void main(String[] args) throws Java.io.IOException {
Java.util.jar.JarFile jarfile = new Java.util.jar.JarFile(new Java.io.File("E:/sqljdbc4.jar")); //jar file path(here sqljdbc4.jar)
Java.util.Enumeration<Java.util.jar.JarEntry> enu= jarfile.entries();
while(enu.hasMoreElements())
{
String destdir = "E:/abc/"; //abc is my destination directory
Java.util.jar.JarEntry je = enu.nextElement();
System.out.println(je.getName());
Java.io.File fl = new Java.io.File(destdir, je.getName());
if(!fl.exists())
{
fl.getParentFile().mkdirs();
fl = new Java.io.File(destdir, je.getName());
}
if(je.isDirectory())
{
continue;
}
Java.io.InputStream is = jarfile.getInputStream(je);
Java.io.FileOutputStream fo = new Java.io.FileOutputStream(fl);
while(is.available()>0)
{
fo.write(is.read());
}
fo.close();
is.close();
}
}
}
JarFile クラス。
JarFile file = new JarFile("file.jar");
for (Enumeration<JarEntry> enum = file.entries(); enum.hasMoreElements();) {
JarEntry entry = enum.next();
System.out.println(entry.getName());
}
これは、jarから「リソース」フォルダー全体を抽出するために行うことです。 BufferedReaderとBufferedWriterを使用する方がはるかに高速です。
public static boolean extractResourcesToTempFolder() {
try {
//If folder exist, delete it.
String destPath = getTempDir() + File.separator + "JToolkit" + File.separator;
deleteDirectoryRecursive(new File(destPath));
JarFile jarFile = new JarFile(JToolkit.class.getProtectionDomain().getCodeSource().getLocation().getPath());
Enumeration<JarEntry> enums = jarFile.entries();
while (enums.hasMoreElements()) {
JarEntry entry = enums.nextElement();
if (entry.getName().startsWith("resources")) {
File toWrite = new File(destPath + entry.getName());
if (entry.isDirectory()) {
toWrite.mkdirs();
continue;
}
InputStream in = new BufferedInputStream(jarFile.getInputStream(entry));
OutputStream out = new BufferedOutputStream(new FileOutputStream(toWrite));
byte[] buffer = new byte[2048];
for (;;) {
int nBytes = in.read(buffer);
if (nBytes <= 0) {
break;
}
out.write(buffer, 0, nBytes);
}
out.flush();
out.close();
in.close();
}
System.out.println(entry.getName());
}
} catch (IOException ex) {
Logger.getLogger(Methods.class.getName()).log(Level.SEVERE, null, ex);
return false;
}
return true;
}
古い質問。
これは、次を使用した更新済みの回答です。
Java.nio
は、エントリを効率的に作成およびコピーしますstream
。辞書順でエントリをソートおよび収集します(常に最初にフォルダを作成するため)。Java.util.Zip.ZipFile
(サブクラス)の代わりにJava.util.jar.JarFile
(基本クラス)を使用したことに注意してください。
最後の1つは、アーカイブからファイルを「ちょうど」抽出するために必要ではないことをさらに実行します。
したがって、オーバーヘッドを削減し、セキュリティの問題に関連する例外の発生を防ぎます。ただし、必要に応じてZipFile/ZipEntry
をJarFile/JarEntry
に置き換えることができます。
import Java.io.IOException;
import Java.nio.file.Files;
import Java.nio.file.Path;
import Java.util.Comparator;
import Java.util.List;
import Java.util.stream.Collectors;
import Java.util.Zip.ZipEntry;
import Java.util.Zip.ZipFile;
public class FileUtils {
public static void extractArchive(Path archiveFile, Path destPath) throws IOException {
Files.createDirectories(destPath); // create dest path folder(s)
try (ZipFile archive = new ZipFile(archiveFile.toFile())) {
// sort entries by name to always create folders first
List<? extends ZipEntry> entries = archive.stream()
.sorted(Comparator.comparing(ZipEntry::getName))
.collect(Collectors.toList());
// copy each entry in the dest path
for (ZipEntry entry : entries) {
Path entryDest = destPath.resolve(entry.getName());
if (entry.isDirectory()) {
Files.createDirectory(entryDest);
continue;
}
Files.copy(archive.getInputStream(entry), entryDest);
}
}
}
}
タイトルは質問にあまりマッチしていないようですが、本当に「[a] Java jarファイルを抽出するプログラム」を書きたい」という場合は、必要なのは Class JarFile 。
この非常に単純なライブラリを使用して、jarファイルをpack/unpackできます
とてもシンプル
import Java.io.File;
import Java.util.List;
import fr.stevecohen.jarmanager.JarUnpacker;
class Test {
JarUnpacker jarUnpacker = new JarUnpacker();
File myfile = new File("./myfile.jar");
File unpackDir = new File("./mydir");
List<File> unpacked_files = jarUnpacker.unpack(myfile.getAbsolutePath(), unpackDir.getAbsolutePath());
}
maven依存関係も使用できます
<dependency>
<groupId>fr.stevecohen.jarmanager</groupId>
<artifactId>JarManager</artifactId>
<version>0.5.0</version>
</dependency>
私のリポジトリも必要です
<repository>
<id>repo-reapersoon</id>
<name>ReaperSoon's repo</name>
<url>http://repo-maven.stevecohen.fr</url>
</repository>
最後の依存関係を使用するには、以下のリンクで最後のバージョンを確認してください
バグを見つけたら public issue tracker を使用してください
try-with-resources
を使用したバージョンです。
try (JarFile jarFile = new JarFile(artifact.getFile())) {
for (JarEntry entry : Collections.list(jarFile.entries())) {
try (InputStream is = jarFile.getInputStream(entry)) {
File file = new File(targetDir, entry.getName());
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(is.read());
}
}
}
} catch (IOException e) {
throw new MyException(String.format(
"Unable to open jar %s", artifact.getArtifactId()), e);
}