2016-05-09 53 views
1

我有jar文件langdetect.jar。 它在图像jar文件里面的文件夹路径

shows the project structure inside the jar

所示有一类LanguageDetectioncom/langdetect包的层次结构。 我需要在执行jar文件时从上面的类访问profiles.sm文件夹的路径。

在此先感谢。

+0

你看过这个吗?可能有助于http://stackoverflow.com/questions/573679/open-resource-with-relative-path-in-java; jar或不是在这里,只要它在类路径 – Preuk

+0

我试过使用DetectorFactory.loadProfile(LanguageDetection.class.getResource(“profiles.sm”)。getPath()); 但没有帮助 –

回答

2

Jars只是Zip文件和Java为处理这些提供支持。

的Java 6(或更早)

你可以打开jar文件作为ZipFile和遍历它的条目。每个条目在文件内都有完整的路径名,没有相对路径名称。尽管你必须小心,但所有条目 - 尽管在zip文件中都是绝对的 - 并不是以'/'开始,如果你需要这个,你必须添加它。以下片段将为您提供一个类文件的路径。该className.class结束,即LanguageDetection.class

String getPath(String jar, String className) throws IOException { 
    final ZipFile zf = new ZipFile(jar); 
    try { 
     for (ZipEntry ze : Collections.list(zf.entries())) { 
      final String path = ze.getName(); 
      if (path.endsWith(className)) { 
       final StringBuilder buf = new StringBuilder(path); 
       buf.delete(path.lastIndexOf('/'), path.length()); //removes the name of the class to get the path only 
       if (!path.startsWith("/")) { //you may omit this part if leading/is not required 
        buf.insert(0, '/'); 
       } 
       return buf.toString(); 
      } 
     } 
    } finally { 
     zf.close(); 
    } 
    return null; 
} 

Java的7/8

您可以使用JAR文件Java7文件系统支持打开JAR文件。这允许您在jar文件上进行操作,就好像它是普通的FileSystem一样。所以你可以走文件树,直到你找到你的文件,并从中获取路径。以下示例使用Java8 Streams和Lambdas,Java7的版本可以从此派生,但会稍微大一些。

Path jarFile = ...; 

Map<String, String> env = new HashMap<String, String>() {{ 
     put("create", "false"); 
    }}; 

try(FileSystem zipFs = newFileSystem(URI.create("jar:" + jarFileFile.toUri()), env)) { 
    Optional<Path> path = Files.walk(zipFs.getPath("/")) 
          .filter(p -> p.getFileName().toString().startsWith("LanguageDetection")) 
          .map(Path::getParent) 
          .findFirst(); 
    path.ifPresent(System.out::println); 
} 

您特定的问题

上述解决方案是找到一个JAR或ZIP内部的路径,但可能不是解决您的问题。

林不知道,我是否正确理解你的问题。据我所知,您希望能够访问类文件夹内的任何目的路径。问题在于,类/资源查找机制不适用于文件夹,仅适用于文件。接近的概念是一个包,但是它总是与一个类相关联。

因此,您总是需要通过getResource()方法访问具体文件。例如MyClass.class.getResource(/path/to/resource.txt)

如果资源位于相对于profiles.sm文件夹到一个类及其包装,即/com/languagedetect/profile.sm/你可以建立从引用类的路径,例如在包中的类LanguageDetection和源于此的绝对路径配置文件。SM路径:

String basePath = "/" + LanguageDetection.class.getPackage().getName().replaceAll("\\.", "/") + "/profiles.sm/"; 
URL resource = LanguageDetection.class.getResource(basePath + "myResource.txt"); 

如果只有一个profiles.sm在罐子里的根,干脆去

String basePath = "/profiles.sm/"; 
URL resource = LanguageDetection.class.getResource(basePath + "myResource.txt"); 

如果您有多个罐子中的资源/profiles.sm,你可以访问所有那些通过类加载器和然后提取从类

for(URL u : Collections.list(LanguageDetection.class.getClassLoader().getResources("/profiles.sm/yourResource"))){ 
     System.out.println(u); 
    } 

的URL在这是不可能的任何情况下的Jar文件,而无需访问该zip/jar文件到浏览此路径或文件夹的内容,因为Java不支持浏览类路径中的包或文件夹内的类或资源。你可以使用Reflections这个库,或者扩展上面的ClassLoader例子,通过使用上面的zip例子额外读取检测到的jar包的内容。

+0

HI杰拉尔德,谢谢,但我需要在jre1.6上运行我的jar文件。需要一些替代方案。 –