2016-11-23 5 views
0

если я печатать строки Юникод как Переходов на консоли, используя print метод System.out потока, его печататься, как и ожидалось (как я использую Ubuntu моно в моей консоли вывода, который поддерживает символы UTF).чтения и записи в UTF-8 символов из потока System.in

Но если я пытаюсь читать из символов юникода консоли с кодировкой UTF-8, используя поток System.in, он не читается правильно. Я пробовал много разных способов добиться этого, используя различные классы читателей с потоком System.in, но он никогда не работает. Так кто-нибудь знает, как я мог бы сделать это

Вот пример кода

BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in, "UTF-8")); 
BufferedWriter console = new BufferedWriter(new OutputStreamWriter(System.out, "UTF-8")); 

console.write("p1: Γίνεται πάντως\n"); 
console.flush(); 
System.out.println("p2: Γίνεται πάντως"); 

byte dataBytes[] = keyboard.readLine().getBytes(Charset.forName("UTF-8")); 
System.out.println("p3: " + new String(dataBytes)); 
console.write("p4: " + new String(dataBytes, "UTF-8") + "\n"); 
console.flush(); 
Scanner scan = new Scanner(System.in, "UTF-8"); 

System.out.println("p5: " + (char) System.in.read()); 
System.out.println("p6: " + scan.nextLine()); 
System.out.println("p7: " + keyboard.readLine()); 

и выход на моей консоли:

p1: Γίνεται πάντως 
p2: Γίνεται πάντως 
Δέν 
p3: ��� 
p4: ��� 
Δέν 
p5: Ä 
p6: �� 
Δέν 
p7: ��� 

мой IDE является Netbeans

+2

Можете ли вы разместить свой рабочий код, пожалуйста? –

+0

возможно [дубликат] (http://stackoverflow.com/questions/26077178/how-can-i-make-system-in-input-stream-read-utf-8-characters) –

+0

Я сомневаюсь, что кодировка вашего ' System.in' является 'UTF-8'. –

ответ

1

System.in является InputStream, который представляет собой поток байтов. Для чтения символов вам нужен Reader. Читатель собирается сделать для вас декодирование.

В этом случае вы можете обернуть System.in с помощью InputStreamReader, передав «UTF-8» в качестве второго параметра конструктора.

Scanner console = new Scanner(new InputStreamReader(System.in, "UTF-8")); 
while (console.hasNextLine()) 
    System.out.println(console.nextLine()); 

Update:

Это, скорее всего, кодировка вашего стандартного ввода неправильно. Чтобы проверить, вы можете сравнить массив байтов, который вы получаете от System.in и ожидаемого.

byte [] expected = "Δέν".getBytes("UTF-8"); // [-50, -108, -50, -83, -50, -67] 

byte [] fromStdin = new byte[1024]; 
int c = System.in.read(fromStdin); 
for (int i = 0; i < c-1; i++) { 
    if (expected[i] != fromStdin[i]) { 
     System.out.println(i + ", " + fromStdin[i]); 
    } 
} 

И вы вводите «Δέν» (без двойных кавычек), затем нажмите enter. Если он выводит что-либо, ваш System.in ошибочно кодируется.

Нельзя ли System.in иметь такую ​​же кодировку, как defaultCharset или какое-либо системное свойство?

Не обязательно. Это поток байтов, а не поток символов. Это не может быть поток символов, потому что вы можете/должны иметь возможность подавать его двоичные данные. Изображение или аудио или vedio, что бы вы ни хотели. Он должен поддерживать их. Вот почему это всего лишь InputStream. Это зависит от того, что окружающая среда предоставила вашей программе. И я очень мало знаю о вашей среде. Вам нужно узнать, как изменить свою среду, или выяснить, какая кодировка на самом деле дает вашу программу.

Например, мы имеем UTF-16 текстовый файл utf16.txt, и мы кормим его содержание к нашей программе, кто ожидает, STDIN быть UTF-8 закодированный текст:

java -cp ... our.utf8.Program < utf16.txt 

Это будет читать бред.

+0

Не работает ни – Chris

+0

Да, вы правы. Но как я могу установить кодировку System.in? – Chris

+0

Но почему java.nio.charset.Charset.defaultCharset() возвращает «UTF-8»? не так ли, что кодировка, используемая System.in? – Chris