这就是我想做的:
FileSystem fs1 = FileSystems.newFileSystem(Paths.get("f1.jar"), null);
FileSystem fs2 = FileSystems.newFileSystem(fs1.getPath("/f2.jar"), null);但是我在第二行中得到了一个由FileSystems.newFileSystem()抛出的FileSystems.newFileSystem()。
我做错了什么?
谢谢!
发布于 2014-10-06 16:11:51
首先不得不提取嵌套的jar。
编辑:在甲骨文论坛上的答案,没有给出为什么你必须首先提取jar的明确理由。
这里引用从… Rajendra Gutupalli的博客(com.sun.nio.zipfs的作者):
让我们假设在Zip中嵌套了一个Jar文件。下面的程序打印MANIFEST.MF文件的内容,该文件位于嵌套的jarCompress1.jar 1.jar文件中。 导入java.io.BufferedInputStream;导入java.nio.file.*;导入java.util.HashMap;导入java.util.Map;公共类ReadEntry { public静态void (String.( args)抛出异常{ Path zipfile = Path.get("c:/zips/zip1.zip");Map env =新HashMap();FileSystem manager = FileSystems.newFileSystem(zipfile,env,null);path = Path System.out.println(“读取输入流”);BufferedInputStream bis =新BufferedInputStream(path.newInputStream();int ch = -1;时间((ch = bis.read()) != -1) { System.out.print((char) ch);}}
和另一个一
这里要注意的一点是,zip文件路径可以扩展到文件路径名称中的嵌套zip或jars。例如,/home/userA/zipfile.zip/DirA/dirB/jarFile.jar/META-INF/MANIFEST.MF访问Zip文件“/home/userA/zipfile.zip”中的jar文件“jarFile.jar”。
我无法复制声称的行为。下一个代码:
try (FileSystem fs1 = FileSystems.newFileSystem(Paths.get("f1.zip"), null)) {
Path path = fs1.getPath("/f2.zip/test.txt");
Files.lines(path).forEach(System.out::println);
}给予例外
Exception in thread "main" java.nio.file.NoSuchFileException: f2.zip/test.txt
at com.sun.nio.zipfs.ZipFileSystem.newInputStream(ZipFileSystem.java:544)
at com.sun.nio.zipfs.ZipPath.newInputStream(ZipPath.java:645)
at com.sun.nio.zipfs.ZipFileSystemProvider.newInputStream(ZipFileSystemProvider.java:278)
at java.nio.file.Files.newInputStream(Files.java:152)
at java.nio.file.Files.newBufferedReader(Files.java:2781)
at java.nio.file.Files.lines(Files.java:3741)
at java.nio.file.Files.lines(Files.java:3782)可能有人会确认这是一个bug,或者指出了我代码中的错误。
同时回到你原来的问题。您不能在zip(jar)中创建FileSystem,因为没有FileSystemProvider (查看newFileSystem方法的源代码),它可以从ZipPath创建FileSystem实例。因此,您必须选择提取from外部zip或编写您自己的FileSystemProvider实现。
发布于 2021-07-17 14:39:42
给定像: jar:file:/console/console.jar!/BOOT-INF/lib/generator.jar!/generator/static/这样的jarfile URI
我编写了以下方法来递归提取jars并返回所有文件系统:
private FileSystem getNestedFileSystems(URI generatorAssets) throws IOException {
String[] jarFiles = generatorAssets.toString().split("!");
URI rootJarUri = URI.create(jarFiles[0]);
FileSystem currentFs;
try {
currentFs = FileSystems.getFileSystem(rootJarUri);
} catch (FileSystemNotFoundException fsnf) {
currentFs = FileSystems.newFileSystem(rootJarUri, Map.of("create", "true"));
}
Path currentJar = null;
if (jarFiles.length > 2) {
for (int i = 1; i < (jarFiles.length - 1); i++) {
Path nestedJar = currentFs.getPath(jarFiles[i]);
Path extractedJar = Files.createTempFile("jar-" + i, ".jar");
Files.copy(nestedJar, extractedJar, StandardCopyOption.REPLACE_EXISTING);
currentFs.close();
if (currentJar != null) {
Files.delete(currentJar);
}
currentJar = extractedJar;
currentFs = FileSystems.newFileSystem(URI.create("jar:file:" + extractedJar),
Map.of("create", "true"));
}
}
return currentFs;
}返回一个文件系统列表,这样您就可以在使用后关闭它们,而不是泄漏FD。
发布于 2022-02-21 06:18:01
这个问题至少在Java 14中得到了解决(也许更早)。OP的代码只需进行一次更改:您需要为ClassLoader的第二个参数newFileSystem添加一个显式强制转换。
对于更完整的示例,此代码打印README.md的内容,该内容位于internal.zip存档中,该存档本身位于archive.zip存档中:
import java.io.IOException;
import java.nio.file.*;
public class Test {
public static void main(String[] args) throws IOException {
Path zipfile = Paths.get("archive.zip");
FileSystem manager = FileSystems.newFileSystem(zipfile, (ClassLoader) null);
Path internal = manager.getPath("internal.zip");
FileSystem internalManager = FileSystems.newFileSystem(internal, (ClassLoader) null);
Path internalFile = internalManager.getPath("README.md");
Files.lines(internalFile).forEach(System.out::println);
}
}注意档案中的文件名是区分大小写的.
https://stackoverflow.com/questions/26219534
复制相似问题