Невозможно открыть файл, передав его в качестве параметра в jar

Если я запускаю свой проект внутри IDE, он работает нормально: EXISTS c:\testvideos\[video] ролик\video.mp4

но если я запустил его в консоли Windows, я получаю сообщение об ошибке: NOT exists c:\testvideos\[video] ?????\video.mp

Я пытался:

  • установка chcp 65001
  • добавление параметров -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8
  • пробуем разные кодировки внутри приложения: NOT exists c:\testvideos\[video] ?????\video.mp4 NOT exists c:\testvideos\[video] ?????\video.mp4 NOT exists c:\testvideos\[video] ?????\video.mp4 NOT exists c:\testvideos\[video] ?????\video.mp4

Вот тестовый код:

import java.io.File;
import java.nio.charset.StandardCharsets;

public class TestFileArgument {
    public static void main(String[] args) {
        String fileName = args[0];
//        String fileName = "c:\\testvideos\\[video] ролик\\video.mp4";
        try {
            checkFileExists(fileName);
            checkFileExists(new String(fileName.getBytes("UTF-8"), "windows-1251"));
            checkFileExists(new String(fileName.getBytes("windows-1251"), "UTF-8"));
            checkFileExists(new String(fileName.getBytes("UTF-8"), StandardCharsets.ISO_8859_1.displayName()));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void checkFileExists(String fileName) {
        if (new File(fileName).exists()) {
            System.out.println("EXISTS " + fileName);
        } else {
            System.out.println("NOT exists " + fileName);
        }

    }

}

вот строка запуска консоли: c:\Users\Ariloum\.jdks\openjdk-21\bin\java.exe -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 -jar c:\testvideos\testFileArguments.jar "c:\testvideos\[video] ролик\video.mp4"

если я запускаю его из командного файла, эхо показывает путь правильно, без символов вопросительного знака вместо кириллицы "???????"

Также это не удается, если имя файла содержит два или более пробельных символа подряд " ". Есть ли обходной путь для этого?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
56
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Powershell — ваш друг:

PS C:\Users\goose> [Console]::InputEncoding = [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding
PS C:\Users\goose> Get-Content -Encoding UTF8 .\TestFileArgument.java
import java.nio.file.Files;    
import java.nio.file.Path;     

public class TestFileArgument {
    public static void main(String[] args) {
        String fileName = "[video] ролик/video.mp4";        
        System.out.println(Path.of(fileName));
        System.out.println(Files.exists(Path.of(fileName)));
    }
}
PS C:\Users\goose> javac -encoding UTF-8 TestFileArgument.java
PS C:\Users\goose> java  TestFileArgument
[video] ролик\video.mp4
true
PS C:\Users\goose> 

ОБНОВЛЕНИЕ: передаваемый параметр:

PS C:\Users\goose> [Console]::InputEncoding = [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding

PS C:\Users\goose> gci -Filter *.mp4


    Directory: C:\Users\goose


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        27/05/2024     11:35              0 два.mp4

PS C:\Users\goose> get-content TestFileArgument.java   
import java.nio.file.Files;
import java.nio.file.Path;

public class TestFileArgument {
    public static void main(String[] args) {
        String fileName = args[0];
        Path p = Path.of(fileName);
        System.out.println(p);
        System.out.println(Files.exists(p));
    }
}
PS C:\Users\goose> java TestFileArgument два.mp4    
два.mp4
true
PS C:\Users\goose> 

вы не передаете имя файла в качестве параметра, у меня есть проект maven, который уже настроен в pom.xml для предварительного формирования всего как UTF-8 и работает нормально, если я жестко запрограммирую внешние имена файлов внутри него. проблема начинается, если я скомпилирую его в jar и передам имя файла в качестве аргумента.

Ariloum 26.05.2024 23:25

да, та же ошибка произойдет, если я передам ее как параметр в PowerShell, работающем как класс .java: PS C:\testvideos> c:\Users\Ariloum\.jdks\openjdk-21\bin\javac.exe -encoding UTF-8 .\TestFileArgument.java PS C:\testvideos> c:\Users\Ariloum\.jdks\openjdk-21\bin\java.exe -cp . TestFileArgument.java "c:\testvideos\[video] ролик\video.mp4" NOT exists c:\testvideos\[video] ?????\video.mp4

Ariloum 26.05.2024 23:56

Да я вижу. Должен расследовать

g00se 27.05.2024 00:37

Пожалуйста, смотрите обновление параметров

g00se 27.05.2024 13:06

у меня почему-то не работает. gci показывает правильные имена, но если я запускаю ошибку кода, возникающую java.nio.file.InvalidPathException: недопустимый символ <?> по индексу 0: ???.mp4

Ariloum 27.05.2024 23:19

Можете ли вы открыть новый сеанс Powershell и выполнить эти шаги. В вашем случае создайте крошечный класс Java, показанный в вашем редакторе, в текущем каталоге.

g00se 27.05.2024 23:28

Да, я проделал все эти шаги, я даже установил последнюю версию PowerShell и попробовал несколько разных Java JDK.

Ariloum 28.05.2024 22:51

Похоже, я решил эту проблему с помощью некоторой настройки Windows 10. Я опубликовал еще один ответ, проверьте его ниже. Спасибо за помощь.

Ariloum 28.05.2024 23:03

Попробую с баночкой. Какой способ запуска вы предпочитаете?

g00se 28.05.2024 23:04
Ответ принят как подходящий

Наконец решил эту проблему, изменив настройки Windows 10, есть один, который называется "Beta: Use Unicode UTF-8 for worldwide language support".

Это в настройках языка панели управления/настройках административного языка/изменении языкового стандарта системы.

Если это включено, все работает нормально напрямую с cmd.exe или Runtime.exec.

Также я решил еще одну проблему с именами файлов Exec во время выполнения, обрабатывающую имена с двойными пробелами подряд, например:

String command = "some.exe \"file      n    a m    e   \"";
Process process = Runtime.getRuntime().exec(command.split(" "));

Другие вопросы по теме