[TLDR => Приложение, кодирующее запутанную проблему, но этот документ от Oracle должен помочь .]
Сначала несколько важных общих моментов, касающихся задания кодировки путем установки свойства системы file.encoding
во время выполнения:
Его использование формально не поддерживается и никогдабыл. Из отчета об ошибках Java в 1998 году :
Свойство file.encoding не требуется спецификацией платформы J2SE; это внутренняя деталь реализаций Sun и не должна проверяться или изменяться кодом пользователя .Он также предназначен только для чтения;технически невозможно поддерживать установку этого свойства для произвольных значений в командной строке или в любое другое время во время выполнения программы.
Существует черновой вариант JEP (Предложение по расширению JDK)), JDK-8187041 Использовать UTF-8 в качестве кодировки по умолчанию , которая предлагает:
Использовать UTF-8 в качестве кодировки по умолчанию для виртуальной машины Java, чтобы API-интерфейсы зависели от значения по умолчаниюcharset ведет себя согласованно на всех платформах.
Не обязательно утверждать, что "Это приложение использует кодировку {x}" , поскольку можетбыть несколькими кодировками, связанными с приложением, к которым можно обращаться по-разному, в том числе:
- Кодировка файла для вывода на консоль.
- Кодировка файла исходных файлов приложения.
- Кодировка файлов для файлового ввода-вывода.
- Кодировка файлов путей к файлам.
Все это говорит, Oracle SPECIВсе кодировки, поддерживаемые Java SE 8 .Я не могу найти соответствующий документ для более свежих версий JDK.Обратите внимание, что:
- Кодировки могут зависеть от среды, в зависимости от локали, операционной системы, версии Java и т. Д.
- Почти каждая кодировка имеет хотя бы один псевдоним.Например, имя кодировки для упрощенного китайского языка GBK , но вы также можете использовать CP936 или windows-936 .
- Большинство кодировокне Unicode, так как имена кодировки Unicode содержат строку «UTF».
- Имя кодировки может варьироваться в зависимости от того, как приложение обрабатывает файлы (
java.nio
APIs против java.io
/ java.lang
API.).Например, при выполнении некоторых операций ввода-вывода для турецких файлов в Windows: - Если используются классы
java.nio.*
, укажите -Dfile.encoding = windows-1254 во время выполнения. - Если используются классы
java.lang.*
& java.io.*
, укажите -Dfile.encoding = Cp1254 во время выполнения.
Эта статья DZone содержит полезный фрагмент кода, демонстрирующий, как настройка -Dfile.encoding во время выполнения может влиять на различные настройки.:
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Locale;
import static java.lang.System.out;
/**
* Demonstrate default Charset-related details.
*/
public class CharsetDemo
{
/**
* Supplies the default encoding without using Charset.defaultCharset()
* and without accessing System.getProperty("file.encoding").
*
* @return Default encoding (default charset).
*/
public static String getEncoding()
{
final byte [] bytes = {'D'};
final InputStream inputStream = new ByteArrayInputStream(bytes);
final InputStreamReader reader = new InputStreamReader(inputStream);
final String encoding = reader.getEncoding();
return encoding;
}
public static void main(final String[] arguments)
{
out.println("Default Locale: " + Locale.getDefault());
out.println("Default Charset: " + Charset.defaultCharset());
out.println("file.encoding; " + System.getProperty("file.encoding"));
out.println("sun.jnu.encoding: " + System.getProperty("sun.jnu.encoding"));
out.println("Default Encoding: " + getEncoding());
}
}
Вот несколько примеров вывода при указании -Dfile.encoding = 860 (псевдоним для MS-DOS португальский ) с использованием Java 12 в Windows 10:
run:
Default Locale: en_US
Default Charset: IBM860
file.encoding: 860
sun.jnu.encoding: Cp1252
Default Encoding: Cp860
BUILD SUCCESSFUL (total time: 0 seconds)
Проверьте кодировку, которую вы планируете указать во время выполнения на всех целевых платформах.Вы можете получить неожиданные результаты.Например, когда я запускаю приведенный выше код в Windows 10 с -Dfile.encoding = IBM864 ( PC Arabic ), он работает, но не работает с -Dfile.encoding = IBM420 ( IBM Arabic ).