Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Прокоментировать часть кода


Автор: Golovastik 3.1.2011, 18:25
Прокоментируйте вот этот код, чего не очень ясен.
Код

String consoleEncoding = System.getProperty("consoleEncoding");
if (consoleEncoding != null) {
    try {
        System.setOut(new PrintStream(System.out, true, consoleEncoding));
    } catch (java.io.UnsupportedEncodingException ex) {
        System.err.println("Unsupported encoding set for console: "+consoleEncoding);
    }
}


Добавлено через 1 минуту и 21 секунду
Переменной под названием consoleEncoding 
мы присваиваем что?

Автор: SoulSeeker 3.1.2011, 18:30
Цитата

Переменной под названием consoleEncoding 
мы присваиваем что? 

Текущую кодировку консоли системы.

Автор: Golovastik 3.1.2011, 18:39
Обязательно ли конструктору  getProperty  передавать значение строковое consoleEncoding?

Цитата

System.getProperty("consoleEncoding");

Это мы делаем из-за того что переменная типа Стринг названа consoleEncoding?

Автор: SoulSeeker 3.1.2011, 18:50
Это не конструктор, а статичный метод. Строка "consoleEncoding" -  имя свойства виртуальной машины.

Автор: Golovastik 3.1.2011, 19:01
То есть мы пишем строку: "consoleEncoding" не из-за того что переменная типа string  названа также?

Автор: SoulSeeker 3.1.2011, 19:09
Нет, это просто считывание свойства по его названию. Например, как из ini файла. Тут может гуру java-машины подскажут, как там свойства хранятся.  

Автор: Golovastik 3.1.2011, 19:41
Код

Нет, это просто считывание свойства по его названию. 

Это считывание свойства из класса System по его названию?
то есть в классе System есть объявленное свойство с именем consoleEncoding в который передаётся значение кодировки через метод getProperty?

Автор: mgarin 3.1.2011, 20:13
Давайте с начала...
Код
System.getProperty("consoleEncoding")


Через данный вызов, как уже было сказано, происходит считывание значения параметра "consoleEncoding".
Пишите Вы конкретно "consoleEncoding" потому, что вам нужно узнать "кодировку консоли" (кэп, знаю).
Например, если бы вам нужно было узнать версию Java-машины - вы бы сделали вот так: 
Код
System.getProperty ( "java.version" )


Если вы вообще ничего не передадите как параметр (или пустой текст) Вы получите ошибку (еще при компилляции) или же проблемы при исполнении (в виде возврата null как результата, например).

Откуда берется значение для указанного параметра?
Ответ более чем полностью приведен в описании метода:
Код
    /**
     * Gets the system property indicated by the specified key.
     * <p>
     * First, if there is a security manager, its
     * <code>checkPropertyAccess</code> method is called with the key as
     * its argument. This may result in a SecurityException.
     * <p>
     * If there is no current set of system properties, a set of system
     * properties is first created and initialized in the same manner as
     * for the <code>getProperties</code> method.
     *
     * @param      key   the name of the system property.
     * @return     the string value of the system property,
     *             or <code>null</code> if there is no property with that key.
     *
     * @exception  SecurityException  if a security manager exists and its
     *             <code>checkPropertyAccess</code> method doesn't allow
     *              access to the specified system property.
     * @exception  NullPointerException if <code>key</code> is
     *             <code>null</code>.
     * @exception  IllegalArgumentException if <code>key</code> is empty.
     * @see        #setProperty
     * @see        java.lang.SecurityException
     * @see        java.lang.SecurityManager#checkPropertyAccess(java.lang.String)
     * @see        java.lang.System#getProperties()
     */
    public static String getProperty(String key)


Добавлено через 2 минуты и 9 секунд
Т.е. в итоге значение берется из некого системного хранилища/хранилища java-машины.
Могу предположить, что при запуске jvm они все считываются в некую мапу и там хранятся до завершения работы.

Автор: SoulSeeker 3.1.2011, 20:15
Цитата(Golovastik @  3.1.2011,  19:41 Найти цитируемый пост)
Это считывание свойства из класса System по его названию?

Опять нет. Свойства не хранятся в коде. Они лежат вне программы - в виртуальной машине и ОС.

Код

Java application programs are executed inside a Java Virtual Machine (JVM), which is in turn executed inside an Operating System (OS). 
From the Java application program point of view, the JVM, together with the OS, represents the computer system. 
The properties of the JVM and the OS are all called system properties. 


Вот тут кратко и понятно: http://www.herongyang.com/Java/System-JVM-and-OS-System-Properties.html

Автор: Golovastik 3.1.2011, 21:05
Код

Через данный вызов, как уже было сказано, происходит считывание значения параметра "consoleEncoding".

А это само свойство находится в классе System? Оно находится в этом классе,в него виндоус отправляет кодировку, которая потом извлекается методом getProperty?

Скажите, а если ОС Линукс, как постатвить условие, что если например в ОС не установлена кодировка CP866 установить её?
Код

if (consoleEncoding != null) //Если переменная consoleEncoding не равна нулю,
 а как она может быть ему равна? 


Автор: nc30 3.1.2011, 21:32
Цитата

Прокоментируйте вот этот код

Чтобы у вас не было путаницы, я поменял название переменной (смысл не изменился)
Код

// Попытка прочитать системное свойство с ключом "consoleEncoding" и записать его значение
// в переменную consEnc
// Если системного свойства с таким ключом не существует, то метод getProperty() вернет null
String consEnc = System.getProperty("consoleEncoding");
// Если такое свойство существует...
if (consEnc != null) {
    try {
        // Попытка переопределить стандартный поток вывода System.out,
        // используя для его создания название символьной кодировки из перем-й consEnc
        System.setOut(new PrintStream(System.out, true, consEnc));
    } catch (java.io.UnsupportedEncodingException ex) {
        System.err.println("Unsupported encoding set for console: "+consEnc);
    }
}


Golovastik, кстати, вывести полный список системных свойств довольно легко. Поместите в ваш код следующие строки:
Код

        // Получаем таблицу значений всех свойств
        Properties props = System.getProperties();
        // Получаем набор имен (ключей) всех свойств
        Set<String> propNames = props.stringPropertyNames();
        // Проходим по множеству ключей, вытаскивая из таблицы соответствующие ключам значения свойств и печатаем их
        for (String key: propNames) {
            System.out.println(key + ": " + props.getProperty(key));
        }


Видимо, идея автора приведенного вами кода была в смене кодировки стандартного потока вывода на другую. Например, чтобы метод System.out.println() делал вывод в иной кодировке (значение которой, как предполагается, задано свойством с именем consoleEncoding). 

Цитата

Код

if (consoleEncoding != null) //Если переменная consoleEncoding не равна нулю,
 а как она может быть ему равна? 


У себя в WinXP я свойства с таким ключом не нашел. Поэтому в моем случае как-раз таки возвращается null. Может быть в Linux есть свойство с таким именем. Как проверить? См. выше про печать списка свойств.


Автор: Golovastik 3.1.2011, 23:15
Попробовал сделать русский ввод, не получается, только вывод русский, как сделать ввод ан русском языке?
Код

package javaapplication3;
import java.io.*;

class Main{
public static void main(String[] args) throws Exception{
System.setOut(new PrintStream(System.out,true,"Cp866"));
    BufferedReader obj = new BufferedReader(new InputStreamReader(System.in));
    String str;
    System.out.println("Введите текст");
    str = obj.readLine();
    System.out.println("Вы ввели: "+str);
}
 }



Результат:
Код

Введите текст
привет
Вы ввели: ЇаЁў?в

Автор: Temdegon 3.1.2011, 23:41
Потому что нужно указать кодировку ввода.
Цитата

BufferedReader obj = new BufferedReader(new InputStreamReader(System.in, "cp1251"));

Какую именно кодировку указывать - я не знаю. 
Если запускаю из нетбинса, то все правильно отображает с такими настройками:
Код

System.setOut(new PrintStream(System.out,true,"UTF-8"));
BufferedReader obj = new BufferedReader(new InputStreamReader(System.in, "cp1251"));

Если запустить из виндовой консоли - то отображает криво.
Как ее правильно определить в рантайме, что бы работало везде и всегда - понятия не имею. Буду благодарен за подсказку.

Автор: nc30 4.1.2011, 09:47
Спасибо Skipy за http://www.skipy.ru/technics.html#io посвященных вводу-выводу, кодировкам и т. п.

Автор: Golovastik 6.1.2011, 15:40

Вот так тоже не хочет, вводить русским в командной строке.
 
Код

System.setIn(new PrintStream(System.in,true,"Cp866"));

Автор: priam220 6.1.2011, 17:25
В JDK6 появился класс Console, позволяющий решить вопросы с кодировкой:

Код

 public class MyClass{

    public static void main(String [] str){
        Console console = System.console();
        String strin = console.readLine();
        console.printf(strin);
    }
}


Вывод: 
Код

D:\Workspaces\workspace1\_example_proj\bin>java default_pack.MyClass
ыыы
ыыы
D:\Workspaces\workspace1\_example_proj\bin>

Автор: nc30 7.1.2011, 07:51
Цитата(Golovastik @ 6.1.2011,  15:40)
Вот так тоже не хочет, вводить русским в командной строке.
 
Код

System.setIn(new PrintStream(System.in,true,"Cp866"));

Кодировку потока out для консоли тоже нужно переустановить
Код

System.setOut(new PrintStream(System.out, true, "Cp866"));


UPD:
Не заметил последнего поста smile

Автор: Golovastik 8.1.2011, 20:47
Да вы не поняли меня, вывод делается на русском, после вот этой строки.
Код

     System.setOut(new PrintStream(System.out,true,"Cp866"));


Мне нужен ВВОД на русском 
Кто-нибудь знает?

Автор: dorogoyIV 8.1.2011, 21:07
для GUI
Код

  Locale locale = new Locale("ru", "RU");
  getInputContext().selectInputMethod(locale);


для консоли - лень возиться  smile 
а оно тебе надо?!  smile 

Автор: Golovastik 8.1.2011, 21:21
Мне нужно сделать консольный ввод и вывод и то и другое. Вывод вот так:
Код

System.setOut(new PrintStream(System.out,true,"Cp866"));


А ввод как сделать?

Автор: dorogoyIV 8.1.2011, 21:27
Цитата(Golovastik @  8.1.2011,  21:21 Найти цитируемый пост)
А ввод как сделать?

подключиться к ОС
переключить раскладку клавы
...
далее по моему не нужно рассказывать  smile 

Автор: Golovastik 8.1.2011, 21:33
Подскажите, как в коде это выразить, так образно я тоже понимаю что это надо сделать.

Автор: dorogoyIV 8.1.2011, 21:52
Цитата(Golovastik @  8.1.2011,  21:33 Найти цитируемый пост)
Подскажите, как в коде это выразить, так образно я тоже понимаю что это надо сделать.

ты хочешь всего и сразу!  smile 
что бы подключиться к ОС, одной Java мало.
для начинающего, я думаю не надо сразу лезть в эти дебри (JNI/JNA)

пиши в консоли в транслите!

Автор: Golovastik 8.1.2011, 22:25
Если кто-нибудь знает как кодом написать чтоб был русский ввод, напишите.
Заранее благодарю.

Автор: mgarin 9.1.2011, 00:54
Цитата(Golovastik @  8.1.2011,  22:25 Найти цитируемый пост)
Если кто-нибудь знает как кодом написать чтоб был русский ввод, напишите.
Заранее благодарю.


Смотря, опять же, что Вы под этим подразумеваете...

Если переключение раскладки в ОС - то конкретно на Java - никак.
Хоть этот функционал есть в каждой ОС - это нативная вещь, а Java и нативные вещи - несовместимые понятия...
Даже распознание языка ввода работает не везде и не всегда, а уж переключение вообще только в мечтах.
Я давно искал решения этого вопроса, так что точно могу сказать - без нативных средств (т.е. скажем отдельного приложения на C, производящего переключение раскладки по запросу Java-приложения) вам не обойтись, а с этим я не думаю, что Вы будете сейчас заморачиваться.

Если же проблема в кодировке - вроде выше уже приводили решения проблемы?.. Они не подошли/не работают?

P.S. Я вообще, впринципе, не особо понял в чем проблема - неужели Вы в консоли не можете поменять руками раскладку? И вводить далее на русском...
Если же в итоге в приложении Вы получаете что-то не то - то это уже проблемы кодировки при считывании ввода - о том как их решить выше, вроде как, разъяснили smile

Автор: Golovastik 9.1.2011, 02:44
Я хочу написать банальное. 
ВВедите текст. Человек вводит на русском текст, а потом оператором вывода, выводится на русском текст.
А получается вот такое:
Код


package javaapplication3;
import java.io.*;
 
class Main{
public static void main(String[] args) throws Exception{
System.setOut(new PrintStream(System.out,true,"Cp866"));
    BufferedReader obj = new BufferedReader(new InputStreamReader(System.in));
    String str;
    System.out.println("Введите текст");
    str = obj.readLine();
    System.out.println("Вы ввели: "+str);
}
 }
 


И при выводе слова Привет я вижу такое:
Код


Введите текст
привет
Вы ввели: ЇаЁў?в
 

Как сделать ,чтоб такого вывод не происходило.
Напишите кодом пожалуйста.

Автор: mgarin 9.1.2011, 03:29
Сразу бы так расписал, было бы гораздо быстрее решить проблему smile

Попробовал разные варианты - вот так (лично у меня) работает:
Код
import java.io.BufferedReader;
import java.io.InputStreamReader;

class Main2
{
    public static void main ( String[] args ) throws Exception
    {
        System.out.println ( "Введите текст" );

        BufferedReader obj =
                new BufferedReader ( new InputStreamReader ( System.in, "Windows-1251" ) );
        String str = obj.readLine ();

        System.out.println ( "Вы ввели: " + str );
    }
}


Собственно, на выходе вышло все как надо:
Код
Введите текст
abcde тест абвгде
Вы ввели: abcde тест абвгде


Т.е. вам нужно просто корректно задать кодировку для ридера строки, ничего волшебного smile

P.S. Единственная оговорка - я проверял в IDEA IDE. Не уверен, что она не подмешивает чего эдакого при выводе smile
Хотя, впринципе, не должна. Попробуйте, отпишитесь если что не пашет

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)