Как вывести список файлов внутри файла JAR? - PullRequest
105 голосов
/ 15 сентября 2009

У меня есть этот код, который читает все файлы из каталога.

    File textFolder = new File("text_directory");

    File [] texFiles = textFolder.listFiles( new FileFilter() {
           public boolean accept( File file ) {
               return file.getName().endsWith(".txt");
           }
    });

Отлично работает. Он заполняет массив всеми файлами, заканчивающимися на «.txt» из каталога «text_directory».

Как я могу прочитать содержимое каталога аналогичным образом в файле JAR?

Итак, что я действительно хочу сделать, это перечислить все изображения внутри моего JAR-файла, чтобы я мог загрузить их с помощью:

ImageIO.read(this.getClass().getResource("CompanyLogo.png"));

(Это работает, потому что «CompanyLogo» является «жестко закодированным», но число изображений в файле JAR может быть от 10 до 200 переменной длины.)

EDIT

Итак, я думаю, что моей главной проблемой будет: Как узнать имя файла JAR , где живет мой основной класс?

Конечно, я мог прочитать это, используя java.util.Zip.

Моя структура такая:

Они похожи:

my.jar!/Main.class
my.jar!/Aux.class
my.jar!/Other.class
my.jar!/images/image01.png
my.jar!/images/image02a.png
my.jar!/images/imwge034.png
my.jar!/images/imagAe01q.png
my.jar!/META-INF/manifest 

Прямо сейчас я могу загрузить, например, «images / image01.png», используя:

    ImageIO.read(this.getClass().getResource("images/image01.png));

Но только потому, что я знаю имя файла, в остальном я должен загружать их динамически.

Ответы [ 13 ]

3 голосов
/ 15 сентября 2009

JAR-файл - это просто zip-файл со структурированным манифестом. Вы можете открыть файл jar с помощью обычных инструментов java zip и сканировать содержимое файла таким образом, раздувать потоки и т. Д. Затем использовать это в вызове getResourceAsStream, и все должно быть в порядке.

РЕДАКТИРОВАТЬ / после уточнения

Мне потребовалась минута, чтобы вспомнить все кусочки, и я уверен, что есть более чистые способы сделать это, но я хотел видеть, что я не сумасшедший. В моем проекте image.jpg - это файл в некоторой части основного файла jar. Я получаю загрузчик классов основного класса (SomeClass является точкой входа) и использую его для обнаружения ресурса image.jpg. Затем какая-то потоковая магия, чтобы включить это в ImageInputStream и все в порядке.

InputStream inputStream = SomeClass.class.getClassLoader().getResourceAsStream("image.jpg");
JPEGImageReaderSpi imageReaderSpi = new JPEGImageReaderSpi();
ImageReader ir = imageReaderSpi.createReaderInstance();
ImageInputStream iis = new MemoryCacheImageInputStream(inputStream);
ir.setInput(iis);
....
ir.read(0); //will hand us a buffered image
1 голос
/ 05 октября 2009

Есть две очень полезные утилиты, которые называются JarScan:

  1. www.inetfeedback.com / jarscan

  2. jarscan.dev.java.net

См. Также этот вопрос: JarScan, отсканируйте все файлы JAR во всех подпапках для определенного класса

0 голосов
/ 17 июня 2015

Просто другой способ перечисления / чтения файлов с URL-адреса jar, и он делает это рекурсивно для вложенных jar

https://gist.github.com/trung/2cd90faab7f75b3bcbaa

URL urlResource = Thead.currentThread().getContextClassLoader().getResource("foo");
JarReader.read(urlResource, new InputStreamCallback() {
    @Override
    public void onFile(String name, InputStream is) throws IOException {
        // got file name and content stream 
    }
});
...