Кодирование имен файлов в Java

Я запускаю небольшое приложение Java на встроенной платформе Linux. После замены Java VM JamVM на OpenJDK имена файлов со специальными символами не сохраняются правильно. Специальные символы, такие как умляуты, заменяются вопросительными знаками.

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

import java.io.File;
import java.io.IOException;

public class FilenameEncoding
{

        public static void main (String[] args) {
                String name = "umlaute-äöü";
                System.out.println("\nname = " + name);
                System.out.print("name in Bytes: ");
                for (byte b : name.getBytes()) {
                        System.out.print(Integer.toHexString(b & 255) + " ");
                }
                System.out.println();

                try {
                        File f = new File(name);
                        f.createNewFile();
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }

}

Его запуск дает следующий результат:

name = umlaute-???
name in Bytes: 75 6d 6c 61 75 74 65 2d 3f 3f 3f

а файл называется umlaute - ??? создано.

Установка свойств file.encoding и sun.jnu.encoding в UTF-8 дает правильные строки в терминале, но созданный файл по-прежнему umlaute - ???

Запустив виртуальную машину с помощью strace, я вижу системный вызов

open("umlaute-???", O_RDWR|O_CREAT|O_EXCL|O_LARGEFILE, 0666) = 4

Это показывает, что проблема не в файловой системе, а в одной виртуальной машине.

Как можно установить кодировку имени файла?


person Roland Brand    schedule 11.04.2012    source источник
comment
Перейдите по ссылке, объясняющей настройку кодировки .. stackoverflow.com/questions/361975/   -  person Phani    schedule 11.04.2012
comment
Настройка file.encoding не помогает. Это влияет только на содержимое файла, но не на имя файла.   -  person Roland Brand    schedule 11.04.2012
comment
Это может вам немного помочь .. stackoverflow.com/questions/1184176/   -  person Phani    schedule 11.04.2012
comment
Вы проверили, поддерживает ли нижележащая файловая система даже UTF-8?   -  person Kru    schedule 11.04.2012
comment
Я согласен с Кру, вы должны убедиться, что файловая система позволяет это. Я столкнулся с той же проблемой с дистрибутивом RedHat, хотя для локали был установлен английский язык и UTF-8. В моем случае самым простым решением было переименовать файлы, но, возможно, для вас это не то же самое.   -  person Sorin    schedule 11.04.2012
comment
Я уверен, что это не проблема файловой системы. Я могу создавать эти файлы в командной строке. Кроме того, другая виртуальная машина, JamVM, может правильно создавать и обрабатывать такие файлы. strace показывает, что вызов open () уже содержит вопросительные знаки вместо ä, ö и ü.   -  person Roland Brand    schedule 11.04.2012
comment
(Стандартная тирада скопирована из другого ответа.) Не используйте new String(bytes[]), не используйте string.getBytes(), не используйте новый InputStreamReader(InputStream) и делайте не использовать new OutputStreamWriter(OutputStream). Они используют кодировку платформы по умолчанию, которая эквивалентна зависимости от глобальной переменной с существенно случайным значением. Укажите кодировку, которую вы используете, если вы не хотите, чтобы ваша программа неожиданно прерывалась необъяснимым образом в какой-то непредсказуемый момент в будущем на какой-либо другой платформе или для другого пользователя.   -  person Christoffer Hammarström    schedule 12.04.2012


Ответы (3)


Если вы используете Eclipse, вы можете перейти в Window-> Preferences-> General-> Workspace и выбрать нужный вариант «Кодировка текстового файла» в раскрывающемся меню. Изменив свою, я смог воссоздать вашу проблему (а также вернуться к исправлению).

Если это не так, вы можете добавить переменную среды в окна (Свойства системы-> Переменные среды и в системных переменных, которые вы хотите выбрать New ...) Имя должно быть (без кавычек) JAVA_TOOL_OPTIONS, а значение должно быть установлено на -Dfile.encoding=UTF8 (или любая другая кодировка, которая заставит вашу работать.

Я нашел ответ в этом сообщении, кстати: Установка кодировки символов Java по умолчанию?

Решения для Linux

- (Постоянно) Использование env | grep LANG в терминале даст вам один или два ответа о том, с какой кодировкой Linux в настоящее время настроен. Затем вы можете установить LANG на UTF8 (ваш может быть установлен на ASCII) в файле / etc / sysconfig i18n (я тестировал это на Fedora 2.6.40). По сути, я переключился с UTF8 (где у меня были нечетные символы) на ASCII (где у меня были вопросительные знаки) и обратно.

- (при запуске JVM, но может не решить проблему) Вы можете запустить JVM с нужной кодировкой, используя java -Dfile.encoding = **** FilenameEncoding Вот результат, полученный двумя способами:

[youssef@JoeLaptop bin]$ java -Dfile.encoding=UTF8 FilenameEncoding

name = umlaute-הצ�
name in Bytes: 75 6d 6c 61 75 74 65 2d d7 94 d7 a6 ef bf bd 
UTF-8
UTF8

[youssef@JoeLaptop bin]$ java FilenameEncoding

name = umlaute-???????
name in Bytes: 75 6d 6c 61 75 74 65 2d 3f 3f 3f 3f 3f 3f 3f 
US-ASCII
ASCII

Вот несколько ссылок на материал Linux http://www.cyberciti.biz/faq/set-environment-variable-linux/

а вот один о -Dfile.encoding Установка кодировки символов Java по умолчанию?

person Youssef G.    schedule 11.04.2012
comment
Я проверил кодировку имени файла в скомпилированном .class-файле. Вот это правильно. Тот же .class-File работает на настольном linux, но не на встроенном. - person Roland Brand; 11.04.2012
comment
не могли бы вы дать больше информации об используемом Linux? Идея та же, вам просто нужно адаптировать ее к программе / ОС, которая запускает JVM. - person Youssef G.; 11.04.2012
comment
Это ядро ​​2.6.30, работающее на процессоре ARM v5 (Atmel AT91SAM9G20). Интересным фактом является то, что JamVM может обрабатывать такие имена файлов, а OpenJDK - нет. От каких функций ОС зависит OpenJDK? - person Roland Brand; 12.04.2012
comment
обновил свой ответ! надеюсь, это поможет. Вы также можете использовать поток ввода и вывода, но я думаю, ваша проблема в том, что Linux настроен с LANG, который не поддерживает ваши символы. Я мог бы заставить свой правильно записать файл, только если бы я был на правильном LANG, кстати. Иначе бы я не получил ??? (хотя терминал показывал ???), но я бы получил следующее: ×× ¦ï¿½ - person Youssef G.; 12.04.2012

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

  • Исходная кодировка в UTF8 (project.build.sourceEncoding в UTF-8 в свойствах maven)
  • Аргументы программы: -Dfile.encoding = utf8 и -Dsun.jnu.encoding = utf8
  • Использование java.nio.file.Path вместо java.io.File
person Stefan A    schedule 17.06.2017

Ваша проблема в том, что javac ожидает для вашего .java-файла другую кодировку, чем вы сохранили как. Не javac предупреждал вас при компиляции?

Возможно, вы сохранили его в кодировке ISO-8859-1 или windows-1252, а javac ожидает UTF-8.

Укажите правильную кодировку javac с флагом -encoding или эквивалентную кодировку для вашего инструмента сборки.

person Christoffer Hammarström    schedule 12.04.2012