Кодировать cp-1252 как utf-8?

Я пытаюсь написать приложение Java, которое будет работать на сервере Linux, но будет обрабатывать файлы, созданные на устаревших машинах Windows, используя cp-1252 в качестве набора символов. Можно ли как-то закодировать эти файлы как utf-8 вместо cp-1252, как он генерируется?


person IAmYourFaja    schedule 20.08.2012    source источник
comment
На этот вопрос нельзя ответить в том виде, в каком он опубликован... он полностью зависит от того, что используется для создания этих файлов (и вы нам об этом не сказали). Если это Excel 2007, то ответ - нет.   -  person theglauber    schedule 21.08.2012
comment
Однако Java должна нормально обрабатывать эти файлы Windows, если заданы правильные параметры кодирования.   -  person theglauber    schedule 21.08.2012
comment
Спасибо, @theglauber (+2). Можете ли вы объяснить, почему Excel 2007 может нарушить условия сделки? Кроме того, можете ли вы привести пример правильных параметров кодирования? Спасибо еще раз!   -  person IAmYourFaja    schedule 21.08.2012
comment
Просто говорю из опыта и разочарования. Вы не можете указать кодировку для CSV-файла в Excel 2007. В Java вы должны использовать InputStreamReader с правильной кодировкой (Windows-1252), созданной поверх FileInputStream.   -  person theglauber    schedule 21.08.2012
comment
Спасибо @theglauber - не могли бы вы увидеть мой комментарий под ответом Эрика Грунцке. Ваша рекомендация выше решает мою проблему?   -  person IAmYourFaja    schedule 21.08.2012
comment
Нет, если проблема связана с самим именем файла, см. ответ Джони Саломен ниже, где предлагается установить локаль для Java-процесс.   -  person theglauber    schedule 21.08.2012


Ответы (2)


Если проблема заключается не только в именах файлов, но и в содержимом, самый простой способ решить проблему — установить locale на компьютере с Linux на что-то, основанное на ISO-8859-1, а не на UTF-8. Вы можете использовать locale -a для отображения списка доступных локалей. Например, если у вас есть en_US.iso88591, вы можете использовать:

export LANG=en_US.iso88591

Таким образом, Java будет использовать ISO-8859-1 для имен файлов, что, вероятно, достаточно хорошо. Чтобы запустить программу Java, вам все равно нужно установить системное свойство file.encoding:

java -Dfile.encoding=cp1252 -cp foo.jar:bar.jar blablabla

Если локаль ISO-8859-1 недоступна, вы можете создать ее с помощью localedef. Однако для его установки требуется root-доступ. На самом деле вы можете сгенерировать локаль, использующую CP-1252, если она доступна в вашей системе. Например:

sudo localedef -f CP1252 -i en_US en_US.cp1252
export LANG=en_US.cp1252

Таким образом, Java должна использовать CP1252 по умолчанию для всех операций ввода-вывода, включая имена файлов.

Более подробно здесь: http://jonisalonen.com/2012/java-and-file-names-with-invalid-characters/

person Joni    schedule 21.08.2012

Вы можете читать и записывать текстовые данные в любой кодировке, которую пожелаете. Вот пример быстрого кода:

  public static void main(String[] args) throws Exception
  {
    // List all supported encodings
    for (String cs : Charset.availableCharsets().keySet())
      System.out.println(cs);

    File file = new File("SomeWindowsFile.txt");
    StringBuilder builder = new StringBuilder();

    // Construct a reader for a specific encoding
    Reader reader = new InputStreamReader(new FileInputStream(file), "windows-1252");
    while (reader.ready())
    {
      builder.append(reader.read());
    }
    reader.close();

    String string = builder.toString();

    // Construct a writer for a specific encoding
    Writer writer = new OutputStreamWriter(new FileOutputStream(file), "UTF8");
    writer.write(string);
    writer.flush();
    writer.close();
  }

Если это все еще «задыхается» при чтении, посмотрите, можете ли вы проверить, что исходная кодировка — это то, что вы думаете. В этом случае я указал windows-1252, который является строкой java для cp-1252.

person Eric Grunzke    schedule 20.08.2012
comment
Спасибо @Eric Grunzke (+1) - часть проблемы заключается в том, что иногда сами имена файлов (например, SomeWindowsFile.txt) содержат символ CP-1252, из-за которого Java Reader задыхается. Итак, реальный вопрос: как вы читаете файл, имя файла которого заставляет Java задыхаться из-за недопустимого символа? Еще раз спасибо! - person IAmYourFaja; 21.08.2012
comment
Вам лучше надеяться, что это запускается в Windows, поскольку CP-1252, скорее всего, не будет кодировкой текстового файла по умолчанию в других контекстах. Лучше использовать new InputStreamReader(new FileInputStream(file, "Win1252")) - person obataku; 21.08.2012
comment
@4herpsand7derpsago, как именно это заставляет Reader задыхаться? Можете ли вы продемонстрировать использование SSCCE? - person obataku; 21.08.2012
comment
Я обновил пример кода, чтобы показать, как принудительно использовать кодировку в Reader. Вопрос Вира хороший: мне любопытно, что вы подразумеваете под дросселем и решает ли это проблему. - person Eric Grunzke; 21.08.2012
comment
Извините, я неправильно прочитал ваш комментарий. У вас проблемы с необычными символами в файле name, а не в файле data. Это сложнее. Я бы предложил попробовать решение Джони с установкой -Dfile.encoding=windows-1252. Кроме того, вы можете попробовать новый файл (the/parent/dir).list() и посмотреть, интерпретирует ли Java имя файла по-другому. - person Eric Grunzke; 21.08.2012