(Это работает, потому что "CompanyLogo" "жестко запрограммирован", но количество изображений внутри файла JAR может быть от 10 до 200 переменной длины.)
Редактировать
Итак, я предполагаю, что моей основной проблемой будет: как узнать имя файла JAR, в котором находится мой основной класс?
Конечно, я мог прочитать это с помощью java.util.Zip.
Но только потому, что я знаю имя файла, в остальном мне приходится загружать их динамически.
Переведено автоматически
Ответ 1
CodeSourcesrc= MyClass.class.getProtectionDomain().getCodeSource(); if (src != null) { URLjar= src.getLocation(); ZipInputStreamzip=newZipInputStream(jar.openStream()); while(true) { ZipEntrye= zip.getNextEntry(); if (e == null) break; Stringname= e.getName(); if (name.startsWith("path/to/your/dir/")) { /* Do something with this entry. */ ... } } } else { /* Fail... */ }
Обратите внимание, что в Java 7 вы можете создать FileSystem из файла JAR (zip), а затем использовать механизмы обхода каталогов и фильтрации NIO для поиска по нему. Это упростило бы написание кода, который обрабатывает JAR-файлы и "разнесенные" каталоги.
Ответ 2
Код, который работает как для IDE, так и для файлов .jar:
privatevoidsafeWalkJar(String path, URI uri)throws Exception {
synchronized (getLock(uri)) { // this'll close the FileSystem object at the end try (FileSystemfs= getFileSystem(uri)) { Files.walk(fs.getPath(path)); } } }
private Object getLock(URI uri) {
StringfileName= parseFileName(uri); locks.computeIfAbsent(fileName, s -> newObject()); return locks.get(fileName); }
На самом деле нет необходимости синхронизировать по имени файла; можно просто синхронизировать на одном и том же объекте каждый раз (или создавать метод synchronized), это чисто оптимизация.
Я бы сказал, что это все еще проблематичное решение, поскольку в коде могут быть другие части, которые используют FileSystem интерфейс поверх тех же файлов, и это может помешать им (даже в однопоточном приложении). Кроме того, он не проверяет наличие nulls (например, на getClass().getResource().
Этот конкретный интерфейс Java NIO в некотором роде ужасен, поскольку он вводит глобальный / одноэлементный ресурс, не являющийся потокобезопасным, а его документация крайне расплывчата (много неизвестного из-за специфичных для поставщика реализаций). Результаты могут отличаться у других FileSystem провайдеров (не JAR). Возможно, для этого есть веская причина; я не знаю, я не исследовал реализации.