Каким способом лучше указывать путь к файлу в программе на языке Java? Где лучше хранить используемые программой файлы?
Насколько я понимаю, так делать совсем плохо, ибо мы не знаем, куда пользователь сохранит нашу программу. Можно прописать относительный путь к файлу, скажем вот так:
Image img = new ImageIcon("img.png").getImage();
Но тогда (если только я правильно понял из проделанных экспериментов) чтобы получить полный путь к файлу JVM делает «конкатенацию» текущей директории с прописанным относительным путём. Т.е. если я запускаю программу такой командой:
G:\program\bin>java -jar Program.jar
То JVM будет искать файл по такому расположению:
G:\program\bin\img.png
Насколько я понимаю, так делать совсем плохо, ибо мы не знаем, с какой директории будет запускать пользователь нашу программу. Можно делать что-то вообще интересное и непростое, типа такого:
Image img = new ImageIcon( this.getClass().getResource("img.png") ).getImage();
Здесь поиск файла будет происходить из пакета, где находится класс this.getClass() . (т.е. та самая «конкатенация» происходит с путём к пакету класса) Но ведь наверное плохо мешать файлы классов с файлами ресурсов? Или даже так:
Image img = new ImageIcon( this.getClass().getResource("/img.png") ).getImage();
Здесь поиск файла происходит в директориях classpath . Но по идее, тогда может оказаться несколько подходящих файлов? И что же это будет?! В общем вопросы: Правильно ли то, что я написал? Какие ещё способы существуют? Когда какой способ использовать? Какой способ наилучший (если он существует)?
Отслеживать
задан 24 фев 2016 в 17:13
743 1 1 золотой знак 9 9 серебряных знаков 24 24 бронзовых знака
intellij idea лучше всего так Run -> Edit configuration -> working derictory(указать рабочую директорию)
24 фев 2016 в 17:48
Хранить изображения и другие ресурсы не нуждающиеся в редактировании внутри JAR — нормальная практика. Обычно создают отдельный каталог images на одном уровне с корнем пакета, либо копируют его туда при сборке JAR.
24 фев 2016 в 17:48
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
Общим ответом на это будет просто слово «зависит» — главный вопрос в том, с чем вы работаете. Как правило, java-приложения распространяются в виде jar-архивов, и если у вас есть распространяемые с приложением ресурсы (например, иконки), то они должны либо оказаться именно там, среди классов, либо, если вы распространяете приложение в виде архива и отдельных ресурсов снаружи архива, то вам нужно самому находить расположение jar-файла и вручную восстанавливать путь к ресурсом по аналогии с working directory. В случае, если вы пишете некоторую утилиту, которая обрабатывает аргументы, то вам, скорее всего, придется иметь дело из абсолютными, и с относительными путями — если вы пишете, скажем, ресайзер изображений, то вызов java -jar path/resizer.jar image.png 300×400 потребует простого проброса аргумента внутрь ImageIcon напрямую, без вообще какого-либо анализа.
Другими словами, все описанные методы имеют свое применение, и являются более или менее предпочтительными в зависимости от ситуации; каждый из них не чем-то плох, а неприменим в текущей ситуации. Если вопрос заключается в поиске ресурсов приложения, то лучше всего либо закидывать в jar, либо искать место установки приложения и отсчитывать от него (т.к. working dir может оказатсья любым).
Отслеживать
ответ дан 24 фев 2016 в 18:10
36.1k 2 2 золотых знака 56 56 серебряных знаков 83 83 бронзовых знака
Т.е. в jar-архиве создаётся отдельная папка, в которую заносятся файлы ресурсов, а обращение к ним происходит с помощью 4-ого способа, да?
Как правильно составить путь до файла?

Имеется такая структура проекта:
Задача:
— в FileAppender нужно указать путь к файлу, в который будут записываться логи.
Что я предпринял:
Прописал путь такого вида:
log/$$/log-$$.txt
Но IntellijIDEA выбрасывает исключение:
ERROR FileManager (log/21:04:2021/log-21:04:2021_15:58.txt) java.io.IOException: The filename, directory name, or volume label syntax is incorrect
fileName String The name of the file to write to. If the file, or any of its parent directories, do not exist, they will be created.
что означает, если файл отсутствует по заданному пути, он будет создан. По каким правилам тогда задается путь?
Вопрос:
Что неправильного в моём пути к файлу, в который будут писаться логи?
- Вопрос задан более двух лет назад
- 709 просмотров
Комментировать
Решения вопроса 1

Дмитрий Александров @jamakasi666 Куратор тега Java
Просто IT’шник.
java.io.IOException: The filename, directory name, or volume label syntax is incorrect
имя файла, имя директории, или имя тома некорректно.
В официальной документации Log4J 2 сказано, что
fileName String The name of the file to write to. If the file, or any of its parent directories, do not exist, they will be created.
что означает, если файл отсутствует по заданному пути, он будет создан. По каким правилам тогда задается путь?
Отлично, но есть еще ограничения имен самой ОС и\или ФС в ней.
В Windows это \/:*?<>«|
Также есть ограничения и в самих словах и по ссылке выше найдете и их.
В общем это не проблема самой java, и вообще не проблема, это ограничения ФС и ОС.
Ответ написан более двух лет назад
Jake Taylor @n199a Автор вопроса
А всё же, в линуксе нужно использовать наклонную черту в одну сторону, в windows — в другую. Почему у меня возник такой вопрос. Изначальной я создавал свой xml-файл в Ubuntu, а после попытался запустить проект из-под windows и всё, приехали.

Дмитрий Александров @jamakasi666 Куратор тега Java
Jake Taylor, это тоже специфичные приколы ОС. Есть некоторые варианты как этого избегать, каким пользоваться лучше в конкретной ситуации выбирать уже вам.
Самый тупой вариант, в лоб заменять слэш на обратный. Естественно имеет свои проблемы.
public String replacePathSlash(String path) < return path.replaceAll("\\", "/"); >
Есть вариант точно знать какой разделитель используется в ОС, File.separator он вернет \ или / в зависимости от ОС. Т.е. в тот же xml вы всегда сохраняете пути со своим особым разделителем, ну к примеру | или всегда с \. А при чтении заменяете его на File.separator , при сохранении естественно наоборот. Чтобы не казалось сверх просто есть еще такой прикол FileSystem.getSeparator() и System.getProperty(«file.separator») =D
Есть еще способ, лучший в большинстве случаев.
String correctPath = Paths.get(filePath).toString();
Тут уже вы можете скормить вот такую мешанину «onedir/twodir\\somedir/somefile» а на выходе получите корректный для текущей ОС путь где все слеши будут правильные. Но опять же чтобы жизнь медом не казалась, если путь будет абсолютным то это нужно учитывать т.к. в win нет как такового понятия root точка, аналогично и в unix нет такого понятия как буква диска =D.
Как получить путь к файлу java
getParent() — возвращает «родительскую» директорию по отношению к текущему пути (то есть ту директорию, которая находится выше по дереву каталогов).
File f = new File("c:\\users\\program.txt"); String Parent = f.getParent();
getRoot() — возвращает «корневую» директорию; то есть ту, которая находится на вершине дерева каталогов.
Как указать путь к файлу в java
Чтобы указать путь к файлу в Java , можно использовать класс java.io.File . Существует несколько способов задания пути:
File file = new File("/path/to/file.txt"); // Здесь /path/to/file.txt - абсолютный путь к файлу.
Относительный путь от текущего каталога:
File file = new File("file.txt"); // Здесь file.txt - файл, расположенный в текущем каталоге.
Относительный путь от корня проекта:
File file = new File("src/main/resources/file.txt");