Краткий ответ: не предполагайте, что «путь» URL-адреса является путем к файловой системе.
Я пытаюсь загрузить некоторые данные в лямбду AWS и использую для этого getClass().getResource(). Это возвращает хороший URL-адрес, который в журналах, по-видимому, распечатывает правдоподобный URL-адрес;
Да. (Было бы неплохо, если бы вы показали нам, как выглядит исходный URL-адрес... хотя я могу догадаться.)
Однако, когда я пытаюсь создать файл на основе этого пути, я получаю файл, который при вызове .exists() возвращает false.
ОК, если URL-адрес не имеет протокола «файл:», я бы НЕ ожидал, что это сработает.
Путь в URL — это путь, предназначенный для разрешения обработчиком протокола. Идея состоит в том, что вы используете URL::openStream
, чтобы открыть поток для ресурса, указанного в URL-адресе, а затем прочитать его. Обработчик протокола заботится об интерпретации пути (и т. д.) и настройке потока.
Для URL-адреса «file:» обработчик протокола разрешает путь в файловой системе и предоставляет вам поток для чтения файла.
Для URL-адреса «http:» обработчик протокола устанавливает соединение с сервером, отправляет запрос GET и возвращает вам поток для чтения тела ответа.
Для URL-адреса «jar:» обработчик протокола открывает файл JAR, находит запись в файле JAR и передает вам поток для его чтения.
И так далее.
Если вы посмотрите на них, то только в случае «файл:» есть разумное ожидание, что обработка компонента пути URL-адреса как имени пути файловой системы может работать.
Глядя на путь в вашем вопросе:
file:/var/task/lib/MyLambda-1.0.jar!/com/my/package/folders/file.end
Я предполагаю, что исходный URL был:
jar:file:/var/task/lib/MyLambda-1.0.jar!/com/my/package/folders/file.end
Итак, что это говорит обработчику протокола «jar:»:
- Найдите ресурс, указанный по URL-адресу «file:/var/task/lib/MyLambda-1.0.jar».
- Откройте его как поток файла JAR
- Найдите запись «/com/my/package/folders/file.end» в пространстве имен файла JAR.
- Откройте поток, чтобы прочитать содержимое этой записи.
Обработчик файлового протокола JAR знает, как это сделать. Но (очевидно) класс File
не ... потому что этот «путь» не является путем к файловой системе.
Как вы решаете это, зависит от того, что вам действительно нужно.
- Если вам просто нужен поток для чтения ресурса, используйте вместо этого
getClass().getResourceAsStream(...)
.
- Если это должен быть файл в файловой системе, вам, возможно, придется получить поток (см. выше), скопировать его во временный файл и использовать
File
для временного файла.
Если вы делаете это, потому что хотите писать в «файл», я бы посоветовал вам отказаться от этой идеи. Плохая идея для приложения пытаться обновить свои ресурсы. А в некоторых случаях он просто не будет/не может работать.
person
Stephen C
schedule
06.08.2019