Свойства Java в кодировке UTF-8 в Eclipse

Мне недавно пришлось сменить кодировку веб-приложения, над которым я работаю ISO-xx в utf8, Все прошло гладко, кроме файлов свойств. я добавил -Dfile.encoding=UTF-8 в eclipse.ini и нормальные файлы работают нормально. Однако свойства показывают странное поведение.

Если я копирую utf8 закодировать свойства из Notepad++ и вставить их в Eclipse, они показывают и работают нормально. Когда я снова открываю файл свойств, я вижу некоторые символы Юникода вместо правильных, например:

Zur\u00EF\u00BF\u00BDck instead of Zurück

но приложение все еще работает нормально. Если я начну редактировать свойства, добавлю некоторые специальные символы и сохраню, они отображаются правильно, однако они не работают, и все ранее работавшие специальные символы больше не работают.

Когда я сравниваю локальную версию с CVS, я правильно вижу специальные символы в удаленном файле, и после обновления я снова запускаюсь: приложение работает, но Eclipse отображает символы Unicode.

Я попытался изменить кодировку файла, щелкнув его правой кнопкой мыши и выбрав "Другое: UTF8", но это не помогло. Также сказано: "определено по содержанию: ISO-8859-1"

Я использую Java 6 и Jboss Developer на основе Eclipse 3.3

Я могу жить с этим, редактируя свойства в Notepad++ и вставляя их в Eclipse, но я был бы признателен, если бы кто-нибудь мог помочь мне исправить это в Eclipse.

13 ответов

Решение

Не тратьте свое время, вы можете использовать плагин Resource Bundle в Eclipse

Основной снимок экрана

Старая страница Sourceforge

Файлы свойств по ISO-8859-1 по определению - см. Документацию по классу свойств.

Spring имеет замену, которая может загружаться с указанной кодировкой, используя PropertiesFactoryBean,

РЕДАКТИРОВАТЬ: Как отметил Лоуренс в комментариях, Java 1.6 представил перегрузки для load а также store которые принимают Reader / Writer, Это означает, что вы можете создать считыватель для файла с любой кодировкой и передать его load, к несчастью FileReader по-прежнему не позволяет указать кодировку в конструкторе (аааа), поэтому вы застрянете в цепочке FileInputStream а также InputStreamReader все вместе. Тем не менее, это будет работать.

Например, чтобы прочитать файл с использованием UTF-8:

Properties properties = new Properties();
InputStream inputStream = new FileInputStream("path/to/file");
try {
    Reader reader = new InputStreamReader(inputStream, "UTF-8");
    try {
        properties.load(reader);
    } finally {
        reader.close();
    }
} finally {
   inputStream.close();
}

Это не проблема с Eclipse. Если вы используете класс Properties для чтения и сохранения файла свойств, класс будет экранировать все специальные символы.

Из документации класса:

При сохранении свойств в поток или загрузке их из потока используется кодировка символов ISO 8859-1. Для символов, которые не могут быть непосредственно представлены в этой кодировке, используются экранированные символы Юникода; однако в escape-последовательности допускается только один символ 'u'. Инструмент native2ascii можно использовать для преобразования файлов свойств в другие кодировки и из них.

Из API, метод store():

Символы меньше \u0020 и символы больше \u007E записываются как \uxxxx для соответствующего шестнадцатеричного значения xxxx.

Properties props = new Properties();
URL resource = getClass().getClassLoader().getResource("data.properties");         
props.load(new InputStreamReader(resource.openStream(), "UTF8"));

Работает как шарм

:-)

Есть гораздо более простой способ:

props.load(new InputStreamReader(new FileInputStream("properties_file"), "UTF8"));
Properties props = new Properties();
URL resource = getClass().getClassLoader().getResource("data.properties");         
props.load(new InputStreamReader(resource.openStream(), "UTF8"));

это хорошо работает в Java 1.6. Как я могу сделать это в 1.5, так как класс свойств не имеет метода для парс InputStreamReader,

В описываемом вами процессе слишком много точек, где могут возникать ошибки, поэтому я не буду пытаться угадать, что вы делаете неправильно, но я думаю, что знаю, что происходит под капотом.

EF BF BD это кодированная форма UTF-8 U+FFFDстандартный символ замены, который вставляется декодерами, когда они сталкиваются с некорректным вводом. Похоже, ваш текст сохраняется как ISO-8859-1, затем читается как UTF-8, затем сохраняется как UTF-8, а затем преобразуется в формат свойств с помощью native2ascii используя кодировку платформы по умолчанию (например, windows-1252).

ü => 0xFC // сохранить как ISO-8859-1
0xFC           => U+FFFD              // читается как UTF-8
U+FFFD         => 0xEF 0xBF 0xBD      // сохранить как UTF-8
0xEF 0xBF 0xBD => \u00EF\u00BF\u00BD  // native2ascii

Я предлагаю вам оставить свойство file.encoding в покое. Как и "file.separator" и "line.separator", это не так полезно, как можно было бы ожидать. Вместо этого, вы всегда должны указывать кодировку при чтении и записи текстовых файлов.

Просто еще один плагин Eclipse для файлов *.properties:

Редактор свойств

Вы можете определить файлы UTF-8 .properties для хранения ваших переводов и использовать ResourceBundle для получения значений. Чтобы избежать проблем, вы можете изменить кодировку:

String value = RESOURCE_BUNDLE.getString(key); 
return new String(value.getBytes("ISO-8859-1"), "UTF-8");

Кажется, это работает только для некоторых символов... включая специальные символы для немецкого, португальского и французского языков. Однако у меня возникли проблемы с русскими, хинди и мандаринскими персонажами. Они не конвертируются в формат свойств 'native2ascii', а сохраняются с??????
Единственный способ заставить мое приложение правильно отображать эти символы - поместить их в файл свойств, переведенный в формат UTF-8 - как \u0915 вместо क или \u044F вместо я. Любой совет?

Я рекомендую вам использовать Attesoro ( http://attesoro.org/). Прост и удобен в использовании. И сделано в Java.

Я нашел решение этой проблемы. Вам нужно написать файл (*.properties) используя стандартные "Свойства", пример:

      Properties properties = new Properties();
properties.put("DB_DRIVER", "com.mysql.cj.jdbc.Driver");
    properties.put("DB_URL", "jdbc:mysql://localhost:3306/world");
    properties.put("DB_USERNAME", "root");
    properties.put("DB_PASSWORD", "1111");
    properties.put("DB_AUTO_RECONNECT", "true");
    properties.put("DB_CHARACTER_ENCODING", "UTF-8");
    properties.put("DB_USE_UNICODE", "true");
    
    
    try {
        properties.store(new FileWriter("src/connectionDB/base/db.properties"), "Comment writes");
    } catch (IOException e) {
        System.out.println(e.getMessage());
    }

то вы можете прочитать файл без ошибок:

      try {           
        properties.load(new FileReader("src\\connectionDB\\base\\db.properties"));          
        properties.list(System.out);
    } catch (IOException ex) {
        System.out.println(ex.getMessage());
    }   

или

              try {
        String str = new String(Files.readAllBytes(Paths.get("src/connectionDB/base/db.properties")), StandardCharsets.UTF_8);
        properties.load(new StringReader(str));
        properties.list(System.out);
    } catch (IOException e) {
        System.out.println(e.getMessage());
    }

или

          InputStream inputStream = getClass().getClassLoader().getResourceAsStream("connectionDB/base/db.properties");
    try {
        Reader reader = new InputStreamReader(inputStream, "UTF-8");
        try {           
            properties.load(reader);
            properties.list(System.out);
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    } catch (UnsupportedEncodingException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

неважно.... затем закройте код, создающий этот файл, и используйте файл *.properties

Если свойства предназначены для XML или HTML, безопаснее всего использовать объекты XML. Их читать сложнее, но это означает, что файл свойств может рассматриваться как прямой ASCII, поэтому ничего не будет искажено.

Обратите внимание, что в HTML есть сущности, которых нет в XML, поэтому я сохраняю их, используя прямой XML: http://www.w3.org/TR/html4/sgml/entities.html

Другие вопросы по тегам