Здесь всякая путаница:
getResource
и getResourceAsStream
не могут быть записаны. Вы не можете преобразовать их в файлы и молиться, чтобы вы могли; ресурсы - абстрактные понятия; в частности, абстрактная концепция, которая определенно не дает никаких обещаний относительно возможности записи. Тривиальный случай: обычно «при развертывании» код java находится в файлах jar, и вы не можете записывать в файлы jar таким образом, обычно не хотите, чтобы записывал в файлы jar, и даже если вы это сделали, правильная защищенная установка, как правило, такова, что процесс не может записывать в свой собственный файл jar, поэтому все это упражнение обречено на провал. Вы этим не пользуетесь. вообще.
'писать в то же место, где находится банка' - это в общем подозрительно. Зачем? В windows около 1990 года это было чрезвычайно распространено, но это никогда не было хорошим местом для записи файлов для каждого пользователя на любой ОС, которая не входила в линию DOS / Windows / CPM / MacOS, а 1980-е годы уже давно прошел мимо нас. На данный момент эта модель не была особенно распространенной на Windows уже более десяти лет; вместо этого вы бы написали, например, в папку «Документы» пользователя. Сама модель уступает: запись в тот же каталог, в котором находится исполняемый код, подразумевает, что вы можете писать в код, и это, как правило, ждет, чтобы ваш ящик получил p0wned, поэтому операционные системы массово отказываются от этой модели.
Если вы ДОЛЖНЫ писать в ту же папку, в которой находится jar, ну, это предполагает, что ваш код по необходимости всегда запускается как jar, что является причудливым предположением для кодирования в вашем исходные файлы. Что, если это не баночка, например, при отладке в eclipse? Рядом с записью пути к классам, в которой размещены ваши файлы классов, поэтому для вашего среднего проекта eclipse ~/workspace/projname
, поскольку это каталог, содержащий ~/workspace/projname/bin
, где находятся скомпилированные файлы классов? Хорошо, ты МОЖЕШЬ это сделать. Но вы не хотите этого делать (см. Пункты 1 и 2). Что, если классы получены из сети, сгенерированы «на лету» или иным образом из загрузчика классов, который не имеет понятия «исходная запись пути к классам, откуда она пришла, является ? ' - Просто молитесь, чтобы ваш код никогда не развертывался в таких обстоятельствах? Я бы по крайней мере предложил альтернативный вариант на основе -D
(который вы можете прочитать с помощью System.getProperty
, поэтому в вашем java коде String overrideLocation = System.getProperty("islandersproject.homedir");
и для запуска вашего приложения: java -Dislandersproject.homedir=/Users/islander/documents -jar islandersproject.jar
.
Хорошо, как мне это сделать?
Ну, я сказал, что можно. Но это непросто.
Для любого данного класса вы можете получить место, в которое он был загружен с помощью этой конструкции:
ClassName.class.getResource("ClassName.class").toString()
Пока рассматриваемый класс не является внутренним классом, это работает. Например:
System.out.println(String.class.getResource("String.class").toString())
- попробуйте.
Полученная строка может быть чем угодно. IF это файл (например, если класс /Users/islander/workspace/islandproject/bin/com/foo/island/islandproject/Island.class
, вы получите эта строка с file://
прикреплена к передней части. Если это jar, вы получите что-то вроде: jar:file://Users/islander/blabla/islanderproject.jar!com/foo/island/islandproject/Island.class
- если это jmod, он начинается с jmod:
(запустите это в String на JDK11 или 14, чтобы увидеть его в действии ), если это сеть или генерируется на лету, это будет еще больше exoti c.
Если вы действительно уверены, что хотите это сделать, проанализируйте строку.
Нет то есть, что '.' (текущий рабочий каталог) никоим образом не гарантирует правильности; если вы запустите в командной строке windows, например:
C:
CD \foobar
java -jar d:\workspace\dist\islander.jar
Тогда .
будет совершенно не связанным c:\foobar
, поскольку это был рабочий каталог, в котором вы начали. Поэтому маловероятно будьте правы, даже если вам повезло с этой работой при тестировании (поскольку eclipse и тому подобное установят его в нормальное место, когда вы запустите приложение из eclipse).