2016-05-09 5 views
1

У меня есть файл jar langdetect.jar. имеет иерархию, показанную на изображенииПуть папки внутри файла jar

shows the project structure inside the jar

Существует класс LanguageDetection в com/langdetect пакете. Мне нужно получить доступ к папке profiles.sm из класса выше при выполнении файла jar.

Заранее спасибо.

+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 (и ранее)

Вы можете открыть файл банку в качестве 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 FileSystem для JAR-файлов. Это позволяет работать с файлом jar, как если бы это была обычная FileSystem. Таким образом, вы можете пройти fileTree до тех пор, пока не найдете свой файл и не получите путь от него. В следующем примере используются потоки Java8 и 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 в этом пакете и получить абсолютный путь от этого к профилей.см путь:

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, вы можете получить доступ ко всем из тех, с помощью загрузчика классов, а затем извлечь файл Jar из URL класса

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

в любом случае это невозможно без доступа к файлу почтового индекса/банка с просмотрите содержимое этого пути или папки, потому что Java не поддерживает просмотр классов или ресурсов внутри пакета/папки в пути к классам. Вы можете использовать библиотеку Reflections для этого или расширить пример ClassLoader выше, дополнительно прочитав содержимое обнаруженных банок, используя пример zip сверху.

+0

HI gerald, спасибо, но мне нужно запустить файл jar на jre1.6. Некоторая альтернатива. –

Смежные вопросы