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


Автор: _Y_ 26.12.2021, 13:51
Пытаюсь обработать кирилицу, поступающую в формате UTF-8
Запускаю программу из Intellij idea - всё работает. Компилирю и запускаю JAR - кирилицу программа на понимает. Сделал вот такой простенький тест-код:

Код

import java.io.*;

public class test {

    public static void main(String[] args) {

        try {
            BufferedReader bReader = new BufferedReader(new FileReader(new File("C:/tmp/java_UTF-8_test.txt")));
            String string = bReader.readLine();
            bReader.close();

            String[] array = string.split("-");
            System.out.println(array[0]);

            array = string.split("Д");
            System.out.println(array[0]);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


Файл java_UTF-8_test.txt содержит единственную строку
Код

абагД-ежз


Intellij idea выдаёт ожидаемое:
Код

абагД
абаг


Компилирую в JAR и запускаю:
Код

?°???°????
?°???°????-?????·


Что-то я делаю не так. Подскажете решение?

Автор: SVN74 26.12.2021, 22:38
попробуйте в винде для запуска вписывать это:

java -Dfile.encoding="utf-8" -jar

у винды кодировка cp1251, - как вариант можно узнать кодировку в системе а затем все стрины конвертировать ... (так будет правильней)  

Автор: Старовъръ 26.12.2021, 23:01
Передавать параметр при запуске можно, конечно, но если мы ожидаем всегда читать UTF-8, то лучше прям в коде это и указать:
Код

new BufferedReader(new FileReader(new File("C:/tmp/java_UTF-8_test.txt"), StandardCharsets.UTF_8));

Автор: SVN74 26.12.2021, 23:12
Цитата(Старовъръ @  26.12.2021,  23:01 Найти цитируемый пост)
Передавать параметр при запуске можно, конечно, но если мы ожидаем всегда читать UTF-8, то лучше прям в коде это и указать:

Все равно будут каракули... Проблема именно в выводе. Хотя если вместо utf8 загрузить виндоусовский формат текстового файла без конвертации в utf8, то должно сработать. но это не наш метод,  smile  - что бы все работало на всех системах с разными кодировками - надо конвертировать фалы не на ввод а на вывод согласно системной кодировке. 

Автор: Старовъръ 27.12.2021, 00:30
Цитата(SVN74 @  26.12.2021,  23:12 Найти цитируемый пост)
Все равно будут каракули... Проблема именно в выводе.
Не понимаю почему ты так решил. System.out.println() выводит в системной кодировке, а это именно та кодировка которую ожидает cmd. Так что вывод как раз должен быть верным при условии что считано было верно. Ну разве что кодировка вывода совсем не поддерживает кириллицу типа US-ASCII.
Цитата(SVN74 @  26.12.2021,  23:12 Найти цитируемый пост)
Хотя если вместо utf8 загрузить виндоусовский формат текстового файла без конвертации в utf8, то должно сработать.
Представим что у нас системная кодировка windows-1251, а файл в UTF-8. Если мы проставим -Dfile.encoding="utf-8", то выводиться данные будут неверно. А если -Dfile.encoding="windows-1251", то будут неверно считываться. Т.е. -Dfile.encoding будет работать только в том случае когда кодировка файла совпадает с системной.

Автор: _Y_ 27.12.2021, 09:05
Спасибо за ответы, вечером поэкспериментирую с вашими решениями. Сейчас - толко то, что можно сказать быстро.
  • Проблема возникает не на шаге System.out.println, а ещё на шаге array = string.split("Д"); Наверное, я сделал не самый наглядный код, но сравнение вторых строчек вывода показывает, что букву "Д" компилированный вариант не опознаёт. Видимо, проблема во вводе.
  • Запускать программу с ключом кодировки в командной строке можно бы, но не хочется. Дело в том, что входные данные далеко не всегда будут в одной и той же кодировке кирилицы, да и приходить будут через чтение URL. Я просто максимально локализовал проблему перед тем, как выкладывать свой вопрос.

.............
ЗЫ: Общая задача такая. Написал простенький парсер веб-страницы. Парсер заходит на сайт, позволяющий найти синонимы к русскому слову. Синонимов, понятное дело, несколько, каждый - кликабельный, к нему тоже можно посмотреть синонимы. Проблема в том, что кликая по цепочке синонимов вручную неизбежно входишь в цикл. Вот я и написал простенькоий код, который показывает только те варианты, которые встретились впервые. 

Автор: _Y_ 27.12.2021, 22:07
Цитата(SVN74 @  26.12.2021,  22:38 Найти цитируемый пост)
попробуйте в винде для запуска вписывать это:
java -Dfile.encoding="utf-8" -jar


Спасибо, так работает.



Цитата(Старовъръ @  26.12.2021,  23:01 Найти цитируемый пост)
Передавать параметр при запуске можно, конечно, но если мы ожидаем всегда читать UTF-8, то лучше прям в коде это и указать:
new BufferedReader(new FileReader(new File("C:/tmp/java_UTF-8_test.txt"), StandardCharsets.UTF_8));

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

Распространил решение на свою задачу - чтение из сети:
Код

URL url = new URL(urlString);
URLConnection con = url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8));

Работает.

Спасибо большое smile 

ЗЫ:Мне немного стыдно приходить с простоватыми вопросами. Но на Java профессионально писал лет пятнадцать назад, забыл всё.

Автор: Старовъръ 27.12.2021, 22:39
Из URLConnection можно получить HTTP Header'ы. Если веб ресурс сделан толково, то в ответе будет https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type, в котором так же может присутствовать charset. Этот charset как раз и будет содержать кодировку. Это чтоб не затачиваться именно на UTF-8, а то вдруг на каком-то ресурсе будет одна кодировка, а на другом - другая. Ну а если она не присутствует, тогда уже использовать какое-то умолчание типа UTF-8.

Автор: _Y_ 28.12.2021, 21:53
Старовъръ, понятно. Хорошо бы запомнить. Но в этом проекте вряд ли пригодится. Ведь для каждого ресурса парсер пишется вручную, так что определять кодировку всё равно приходится до написания класса-парсера.

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