Версии программного обеспечения:
- ОС: Windows 10 Pro, версия: 1909, сборка: 18363.720
- IntelliJ IDEA: 2019.2.4 Ultimate
- Версия оболочки Gradle: 5.2.1-all
- jdk: 8
Проблема лежит в кодировки, особенно в выводе консоли в проекте Gradle.
Вот мой файл build.gradle:
Код: Выделить всё
plugins {
id 'java'
id 'idea'
id 'application'
}
group 'com.diceeee.mentoring'
version 'release'
sourceCompatibility = 1.8
application.mainClassName('D')
compileJava.options.encoding = 'utf-8'
tasks.withType(JavaCompile) {
options.encoding = 'utf-8'
}
repositories {
mavenCentral()
jcenter()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
}
Вот D.java:
Код: Выделить всё
import java.io.FileWriter;
import java.io.IOException;
public class D {
public static void main(String[] args) throws IOException {
System.out.println(System.getProperty("file.encoding"));
String testLine = "Проверка работоспособности И Ш";
System.out.println(testLine);
FileWriter writer = new FileWriter("D:\\test.txt");
writer.write(testLine);
writer.close();
}
}
Код: Выделить всё
org.gradle.jvmargs=-Dfile.encoding=utf-8
Когда я запускаю свой проект gradle, я получаю это:
Код: Выделить всё
21:04:53: Executing task 'D.main()'...
> Task :compileJava UP-TO-DATE
> Task :processResources NO-SOURCE
> Task :classes UP-TO-DATE
> Task :D.main()
UTF-8
�������� ����������������� � �
Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/5.2.1/userguide/command_line_interface.html#sec:command_line_warnings
BUILD SUCCESSFUL in 0s
2 actionable tasks: 1 executed, 1 up-to-date
21:04:54: Task execution finished 'D.main()'.
1) Я не случайно оставил вывод в файле в коде. Если мы попытаемся просмотреть файл, то увидим следующее:
Код: Выделить всё
Проверка работоспособности И Ш
2) Я отладил внутренности классов PrintStream, OutputStreamWriter и StreamEncoder. StreamEncoder действительно использует кодировку utf-8, а также закодировал текст utf-8 в нужную последовательность байт:
String testLine = "Проверка работоспособности И Ш";
Каждая буква кириллицы - 2 байта, пробелы - 1 байт, если посчитать все буквы, то получим 57.
Теперь посмотрите здесь:
Экран отладки кодировщика с результатом байт
Итак, как мы видим, мы получаем первые 57 байт (остальные — из других входов, буфер использует ограничения):
Код: Выделить всё
[-48, -97, -47, -128, -48, -66, -48, -78, -48, -75, -47, -128, -48, -70, -48, -80, 32, -47, -128, -48, -80, -48, -79, -48, -66, -47, -126, -48, -66, -47, -127, -48, -65, -48, -66, -47, -127, -48, -66, -48, -79, -48, -67, -48, -66, -47, -127, -47, -126, -48, -72, 32, -48, -104, 32, -48, -88, 91]
Я не знаю. Серьезно. Но есть дополнительная информация. Если это не показалось вам умопомрачительным, я приготовил для вас кое-что еще.
Я создал чистый Java-проект без каких-либо gradle/maven и т. д., только свой собственный jdk и ничего больше.
Программа та же:
Код: Выделить всё
package com.company;
import java.io.FileWriter;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
System.out.println(System.getProperty("file.encoding"));
String testLine = "Проверка работоспособности И Ш";
System.out.println(testLine);
FileWriter writer = new FileWriter("D:\\test.txt");
writer.write(testLine);
writer.close();
}
}
Код: Выделить всё
"C:\Program Files\Java\jdk1.8.0_181\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.2.4\lib\idea_rt.jar=58901:C:\Program Files\JetBrains\IntelliJ IDEA 2019.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar;C:\Users\\IdeaProjects\test\out\production\test" com.company.Main
UTF-8
Проверка работоспособности И Ш
Process finished with exit code 0
Код: Выделить всё
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class D {
public static void main(String[] args) throws IOException {
System.out.println(System.getProperty("file.encoding"));
String testLine = new String("Проверка работоспособности И Ш".getBytes(StandardCharsets.UTF_8), "windows-1251");
System.out.println(testLine);
FileWriter writer = new FileWriter("D:\\test.txt");
writer.write(testLine);
writer.close();
}
}
Код: Выделить всё
21:43:06: Executing task 'D.main()'...
> Task :compileJava
> Task :processResources NO-SOURCE
> Task :classes
> Task :D.main()
UTF-8
Проверка работоспособности �? Ш
Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/5.2.1/userguide/command_line_interface.html#sec:command_line_warnings
BUILD SUCCESSFUL in 0s
2 actionable tasks: 2 executed
21:43:06: Task execution finished 'D.main()'.
Код: Выделить всё
Проверка работоспособности � Ш
Ну, вот полный список того, что я пытался решить проблему:
1) Установите -Dfile.encoding=UTF-8 в idea.exe.vmoptions и idea64.exe.vmoptions с перезапуском. Не помогло.
2) Установите UTF-8 в IntelliJ IDEA -> Настройки -> Редактор -> Кодировки файлов везде. Не помогло.
3) Установите кодировку компилятора Gradle на utf-8. Не помогло.
4) Установите параметр gradle jvm org.gradle.jvmargs=-Dfile.encoding=utf-8. Не помогло.
5) Проверил, что в Windows по умолчанию стоит русский язык для программ, не поддерживающих юникод, для поддержки кириллицы. Не помогло.
Я не уверен, в чем проблема с gradle, потому что чистый проект без gradle работает отлично, вывод на консоль в порядке. Но в Gradle кириллические символы неверны. Кроме того, я пытался как-то исправить вывод на консоль с помощью метода/конструктора getBytes(charset) и new String(byte[], charset), я пробовал эти варианты:
Код: Выделить всё
String testLine = new String("Проверка работоспособности И Ш".getBytes(StandardCharsets.UTF_8), "windows-1251");
Output:
Проверка работоспособности �? Ш
Код: Выделить всё
String testLine = new String("Проверка работоспособности И Ш".getBytes(StandardCharsets.UTF_8), "cp866");
Output:
?�?�???????�???? ?�???????�???�?????�?????????�?�?? ?� ?�
Код: Выделить всё
String testLine = new String("Проверка работоспособности И Ш".getBytes(StandardCharsets.UTF_8), "utf-8");
Output:
�������� ����������������� � �
Кроме того, я попробовал еще одну вещь — обертку System.out для установки другой кодировки консоли.
Код: Выделить всё
public class D {
public static void main(String[] args) throws IOException {
System.out.println(System.getProperty("file.encoding"));
System.setOut(new PrintStream(System.out, true, "utf-8"));
String testLine = "Проверка работоспособности И Ш";
System.out.println(testLine);
FileWriter writer = new FileWriter("D:\\test.txt");
writer.write(testLine);
writer.close();
}
}
Код: Выделить всё
> Task :D.main()
UTF-8
�������� ����������������� � �
Код: Выделить всё
Проверка работоспособности И Ш
Я чувствую себя детективом, но я застрял, застрял в этом деле. Буду благодарен, если кто-нибудь мне поможет.
Подробнее здесь: https://stackoverflow.com/questions/608 ... le-project
Мобильная версия