Подтвердить что ты не робот

Почему мой URI не является иерархическим?

У меня есть файлы в папке с ресурсами. Например, если мне нужно получить файл из папки ресурсов, мне это нравится:

File myFile= new File(MyClass.class.getResource(/myFile.jpg).toURI());             
System.out.println(MyClass.class.getResource(/myFile.jpg).getPath());

У меня проверено и все работает!

Путь

/D:/Java/проекты/.../классы/X/Y/Z/myFile.jpg

Но. Если я создаю файл jar, используя Maven:

mvn package

... и затем запустите мое приложение:

java -jar MyJar.jar

У меня есть следующая ошибка:

Exception in thread "Thread-4" java.lang.RuntimeException: ხელმოწერის განხორციელება შეუძლებელია
Caused by: java.lang.IllegalArgumentException: URI is not hierarchical
        at java.io.File.<init>(File.java:363)

... и путь к файлу:

file:/D:/java/projects/.../target/MyJar.jar!/X/Y/Z/myFile.jpg

Это исключение возникает, когда я пытаюсь получить файл из папки ресурсов. На этой линии. Зачем? Почему эта проблема возникает в JAR файле? Как вы думаете?

Есть ли другой способ, чтобы получить путь к папке ресурса?

4b9b3361

Ответ 1

Вы должны использовать

getResourceAsStream(...);

когда ресурс вставляется в виде jar/war или любого другого отдельного пакета файлов.

Посмотрите, что это такое, jar - это один файл (вроде файла zip), содержащий много файлов вместе. Из Os pov, его одного файла, и если вы хотите получить доступ к part of the file (ваш файл изображения), вы должны использовать его как поток.

Документация

Ответ 2

Вот решение для разработчиков Eclipse RCP/Plugin:

Bundle bundle = Platform.getBundle("resource_from_some_plugin");
URL fileURL = bundle.getEntry("files/test.txt");
File file = null;
try {
   URL resolvedFileURL = FileLocator.toFileURL(fileURL);

   // We need to use the 3-arg constructor of URI in order to properly escape file system chars
   URI resolvedURI = new URI(resolvedFileURL.getProtocol(), resolvedFileURL.getPath(), null);
   File file = new File(resolvedURI);
} catch (URISyntaxException e1) {
    e1.printStackTrace();
} catch (IOException e1) {
    e1.printStackTrace();
}

Очень важно использовать FileLocator.toFileURL(fileURL) вместо resolve(fileURL) , потому что, когда плагин упаковывается в банку, это заставит Eclipse создать распакованную версию во временном местоположении, чтобы к объекту можно было получить доступ с помощью File. Например, я думаю, что у Ларса Фогеля есть ошибка в его статье - http://blog.vogella.com/2010/07/06/reading-resources-from-plugin/

Ответ 3

У меня такая же проблема, когда я работал над проектом в своей компании. Прежде всего, URI не является иерархическим вопросом, потому что, вероятно, вы используете "/" в качестве файлового seperator.

Вы должны помнить, что "/" предназначено для Windows и от ОС до ОС, которые она меняет, в Linux это может быть иначе. Следовательно, используйте File.seperator.

Таким образом, используя

this.getClass().getClassLoader().getResource("res"+File.seperator+"secondFolder")

может удалить URI, а не иерарихал. Но теперь вы можете столкнуться с Null Pointer Exception. Я пробовал много разных способов, а затем использовал JarEntries Class для его решения.

File jarFile = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
        String actualFile = jarFile.getParentFile().getAbsolutePath()+File.separator+"Name_Of_Jar_File.jar";
        System.out.println("jarFile is : "+jarFile.getAbsolutePath());
        System.out.println("actulaFilePath is : "+actualFile);
        final JarFile jar = new JarFile(actualFile);
        final Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
        System.out.println("Reading entries in jar file ");
        while(entries.hasMoreElements()) {
            JarEntry jarEntry = entries.nextElement();
            final String name = jarEntry.getName();
            if (name.startsWith("Might Specify a folder name you are searching for")) { //filter according to the path
                System.out.println("file name is "+name);
                System.out.println("is directory : "+jarEntry.isDirectory());
                File scriptsFile  = new File(name);
                System.out.println("file names are : "+scriptsFile.getAbsolutePath());

            }
        }
        jar.close();

Вы должны указать имя jar здесь явно. Так что используйте этот код, это даст вам каталог и подкаталог внутри папки в банке.