Загрузка файлов в Java не работает, если путь содержит пробелы, например % 20 - PullRequest
2 голосов
/ 29 июня 2019

Я просмотрел множество ответов на тему Java Files и проблемы с путями, даже некоторые с пробелами в пути, но не ответил на мой вопрос, который я хотел бы задать:

Почему следующий кодработать, находясь в непустом каталоге, и почему он не работает в противном случае?

Я разложил свою проблему до самых основных вопросов, поэтому я надеюсь, что кто-нибудь сможет объяснить мне проблему; -)

У меня есть старый API, который я должен передать с помощью файловых дескрипторов некоторых изображений, и я решил загрузить изображения с использованием подхода относительного URL-адреса.

Я знаю, что это не работает сбанки, но я не собираюсь загружать какое-либо изображение из банки еще.Решение достаточно для моих текущих требований, и я не хочу превращать все в потоки на данный момент ...

Но успех любого выполнения в значительной степени зависит от каталога, в котором он выполняется!Мне это кажется странным.

Поэтому я написал тест JUnit и предоставил несколько файлов, которые находятся в каталоге ресурсов для тестирования, для исследования этой проблемы.

└───imageload    
    ├───src
    │   ├───main
    │   │   ├───java
    │   │   └───resources
    │   └───test
    │       ├───java
    │       │   └───stupid
    │       │       └───test
    │       └───resources
    │           └───testset
    └───target
        ├───generated-test-sources
        │   └───test-annotations
        └───test-classes
            ├───stupid
            │   └───test
            └───testset

Это тестовый код, который нужно сделатьпроблема очевидна:

package stupid.test;

[... imports omitted...]

public class SimpleTest {

    public static final File getFileByRelativePathURL(String relativePath) {
        URL url = Thread.currentThread().getContextClassLoader().getResource(relativePath);
        File file = new File(url.getPath());
        return file;
    }

    @Test
    void loadImage() {

        File theFile = SimpleTest.getFileByRelativePathURL("testset/black.jpg");
        Boolean exists = theFile.exists();

        assertTrue(exists);
    }


}

При запуске теста в этом каталоге все работает нормально:

  • D: \ Temp \ working \ imageload \

при запуске его отсюда происходит сбой:

  • D: \ Temp \ не работает \ imageload \

Я более внимательно посмотрел на полученные экземпляры файлов ипространство в каталоге должным образом экранировано в этот путь к объекту файла:

file = D:\Temp\not%20working\imageload\target\test-classes\testset\black.jpg

Но должна быть проблема с% 20, так как файл не может быть найден в соответствии с методом exist ()Класс файла.

Я надеюсь, что проблема может быть очевидна для многих из вас, хотя я все еще ожидаю, что "theFile.exists ()" вернет true в любом каталоге с пробелами или без них.

Чтоя делаю неправильно?

ОБНОВЛЕНИЕ : меня спросили,Мой вопрос является дубликатом этой статьи:

К сожалению, решение не учитывает мое желаниенайти правильный относительный путь.Вместо этого он передает абсолютный путь к конструктору файлов.

Но сочетание с комментарием JB Nizet помогло мне понять проблему ... и хотя это довольно грязное решение, я изменил свой метод относительного URL на этот:

public static final File getFileByRelativePathURL(String relativePath) {
        URL url = Thread.currentThread().getContextClassLoader().getResource(relativePath);
        File file = new File(url.getPath().replaceAll("%20", " "));
        return file;
    }

Теперь все отлично работает ... тупой меня!Я действительно должен сделать это по-другому; -)

1 Ответ

0 голосов
/ 29 июня 2019

Благодаря комментарию Дж. Б. Низета я пришел к решению, которое, вероятно, является скорее "грязным взломом", чем правильным обходным путем, но это эффективное решение для моей текущей проблемы.

Первоначальной ошибкой было моё предположение, что я могу использовать экранированные URL-пути в качестве путей к файлам, что, очевидно, неверно. Поэтому я удалил экранирование пробелов, изменив свой метод относительного пути следующим образом:

public static final File getFileByRelativePathURL(String relativePath) {
        URL url = Thread.currentThread().getContextClassLoader().getResource(relativePath);
        File file = new File(url.getPath().replaceAll("%20", " "));
        return file;
    }

Это делает реальные пробелы из подстановок '% 20', и теперь тесты JUnit работают во всех путях, которые содержат пробелы. Это не решение для других пробелов или экранированных специальных символов.

Я воспользуюсь советом и постараюсь обойти необходимость использования объектов File в старом API, который я использую как можно лучше!

В моем коде я определенно буду отдавать предпочтение Streams! :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...