如何从jar:文件URL构造路径?

时间:2014-08-20 04:52:21

标签: java jar uri

如何构建Pathjar:file网址?

调用Paths.get(new URI("jar:file:/C:/foo.jar!/bar.html")) throws FileSystemNotFoundException(注意文件系统丢失,而不是文件本身)。

据我所知,这两个文件都存在。有什么想法吗?

3 个答案:

答案 0 :(得分:5)

Paths尝试解析包含FileSystem的{​​{1}}。 (实际上这可能是一个实现细节。规范只是声明它会检查默认的Path。)如果你没有注册/创建这样的FileSystem,它将无法找到它

您将从jar文件中创建一个新的FileSystem,并通过该FileSystem访问条目Path

FileSystem

然后你可以使用

Path path = Paths.get("C:/foo.jar");
URI uri = new URI("jar", path.toUri().toString(),  null);

Map<String, String> env = new HashMap<>();
env.put("create", "true");

FileSystem fileSystem = FileSystems.newFileSystem(uri, env);
Path file = fileSystem.getPath("bar.html");
System.out.println(file);

使用完毕后,请务必正确关闭Paths.get(new URI("jar:file:/C:/foo.jar!/bar.html"))

有关ZipFileSystemProvider的更多信息,请参阅here

答案 1 :(得分:1)

从版本7开始,Java允许我们拥有FileSystems,不仅可以在本地目录上打开文件,还可以定义我们自己的文件系统。它有很多用途,比如拥有分布式文件系统,能够使用压缩,有一个http桥,有很多东西......

在您的情况下,您需要的是一种阅读jar的方法。好吧,既然jar只是一个压缩文件,你可以使用默认的FileSystem。它并没有比这更容易:

import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;


public class Main {
    public static void main(String [] args) throws Throwable {
        String jarName = "/Users/asantos/.m2/repository/ant/ant/1.6/ant-1.6.jar";
        String fileInside = "/META-INF/LICENSE.txt";

        Map<String, String> env = new HashMap<>(); 

        URI uri = URI.create("jar:file:"+jarName);

        try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {

            System.out.println(new String(Files.readAllBytes(zipfs.getPath(fileInside))));

        } 
    }
}

我无耻地从文档中复制了我的代码,适应了jar而不是zip文件:http://docs.oracle.com/javase/8/docs/technotes/guides/io/fsp/zipfilesystemprovider.html

答案 2 :(得分:1)

<pre><code>
import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.*; 
public static void method() {
    final Map<String, String> env = new HashMap<>();
       
    // here false is used to indicate the zip file system provider not to create a new zip/jar file if it does not exist.
      
    env.put("create", Boolean.FALSE.toString());
               
   final Path jarFilePath = Paths.get("C:\\test_jar_parent", "myjarfile.jar");
  
   final String uriPath = "jar:" + jarFilePath.toUri().toString();
     
   final URI uri = URI.create(uriPath);
   try (final FileSystem jarFs = FileSystems.newFileSystem(uri, env, null)) {
          …
      }
</code></pre>