Есть вещи, видимо настолько очевидные для опытных разработчиков, что они о таком никогда не пишут, считая что уж ЭТО настолько очевидно, что и разжевывать тут нечего. А новички сталкиваются с совершенно тупыми проблемами и не могут найти как же эту проблему решать.
Одна из таких проблем - работа с ресурсами. На Си меня совершенно не волновало куда положить всякие картинки, звуки и как их потом оттуда взять. Создал папку, накидал как хотел, если много - привел в порядок и поехали. На Java я первоначально именно так и поступил, но потом пришлось чесать репу:
чтобы сделать из приложения апплет, или сделать возможным Web Start - ресурсы должны хранится в jar. Т.е. можно конечно обойтись и без этого, даже в таких случаях, но некошерными методами. Главное засунуть их туда проблемы нет вообще - jar, это тот же zip, и положить что-то внутрь можно даже силами файлового менеджера, многие из них давно умеют обращаться с такими файлами как собычными папками. Но как потом из программы обратится к положенному?
Оказалось все достаточно тривиально (однако чувствуются некоторые подводные камни и спрятанные грабли). Итак, руководство для новичков, как обращаться с ресурсами в Java:
предполагается что вы пользуетесь Eclipse, в прочих IDE не должно сильно отличаться.
- создаем новый package: File->New->Package и даем ему какое-то разумное имя. Например resources. Или images
- ложим туда все наши картинки. Если вы уже сделали простую папку и натолкали их туда - перетаскиваем мышой, если они лежат где-то отдельно, не подключенные к проекту - можно сделать импорт.
- InputStream is=getClass().getResourceAsStream("/images/example.png") - получаем InputStream для файла example.png лежащего в пакете images
- Вуаля!
Если вы привыкли работать с File - отвыкайте. В общем-то он нужен вам чтобы получить все тот же InputStream. Если какие-то методы требуют File, то поищите - и обнаружите что они имеют вариант с InputStream.
Если вы сделали пакет resources.images, то обращение к файлу будет выглядеть так:
InputStream is=getClass().getResourceAsStream("/resources/images/example.png");
Все точки в названии пакета заменяются на / и не забывайте про ведущий слэш.
Если обнаружите что можно сделать так
InputStream is=getClass().getResource("/resources/images/example.png").getFile();
то вдумчиво читайте описание всех упомянутых методов, ничего хорошего у вас так не выйдет :).
Когда придет время явить свое творение миру, вы сформируете единый jar со всем что нужно для счастья при помощи maven, или ручками. Если второй вариант, то не забывайте: во время отладки эклипса сама формирует переменные типа classpath и прочую фигню так чтобы ваша программа видела свои ресурсы - но в bin, как откомпилированные классы, их не копирует. Так что когда будете делать jar, кроме классов не забывайте затолкать лежащие отдельно ресурсы - не нарушая структуры packages.
Т.е. если у вас класс yourpackage.YourApp и ресурс resources.images.example.png, то структура jar-файла:
- yourpackage
- YourApp.java
- resources
- images
- example.png
- images
Про нативные либы песня отдельная. Их ложат в отдельный jar, прямо в корень и подключают к апплету или web start application путем указания соответствующего элемента в jnlp файле.
Если вы не собираетесь делать апплет или webstart - просто положите в отдельную папку и в скрипте запуска вашего приложения укажите путь:
#!/bin/sh
java -Djava.library.path=lib -jar myapp-1.0.0-jar-with-dependencies.jar
в папке где у меня лежит приложение в виде одного jar со всеми прибамбасами и ресурсами myapp-1.0.0-jar-with-dependencies.jar есть еще папочка lib, где валяются нативные либы. Можно сделать несколько папочек, но тогда придется указывать их все через ":".
Комментариев нет:
Отправить комментарий