Java кодировка и Windows
У меня есть Java-программа, которая запускает msinfo32.exe (системная информация) во внешнем процессе, а затем читает содержимое файла, созданного msinfo32.exe. Когда программа Java загружает содержимое файла в строку, символы строки не читаются. Чтобы String был читабельным, я должен создать String с использованием String(byte[] bytes, String charsetName) и установить для charsetName значение UTF-16. Однако при работе в одном экземпляре Windows2003 только UTF-16LE (little-endian) приводит к выводу на печать строки.
Как я могу заранее узнать, какую кодировку использовать?
Кроме того, любая справочная информация по этой теме будет принята с благодарностью.
5 ответов
Некоторые приложения Microsoft используют метку порядка байтов для обозначения файлов Unicode и их порядкового номера. На моем компьютере с Windows XP я вижу, что экспортированный файл.NFO начинается с 0xFFFE, поэтому он имеет младший порядок.
FF FE 3C 00 3F 00 78 00 6D 00 6C 00 20 00 76 00 __<_?_x_m_l_ _v_
65 00 72 00 73 00 69 00 6F 00 6E 00 3D 00 22 00 e_r_s_i_o_n_=_"_
31 00 2E 00 30 00 22 00 3F 00 3E 00 0D 00 0A 00 1_._0_"_?_>_____
3C 00 4D 00 73 00 49 00 6E 00 66 00 6F 00 3E 00 <_M_s_I_n_f_o_>_
0D 00 0A 00 3C 00 4D 00 65 00 74 00 61 00 64 00 ____<_M_e_t_a_d_
Кроме того, я рекомендую вам использовать реализации Reader, а не конструктор String для декодирования файлов; это помогает избежать проблем, когда вы читаете половину символа, потому что он усекается, потому что он находится в конце байтового массива.
Вы можете попытаться использовать библиотеку, чтобы угадать кодировку, например, я однажды использовал это решение.
Вы не можете точно знать, какая кодировка символов использовалась (если вы не создали инструмент, который создал вывод, который вы обрабатываете). Вы можете попытаться обнаружить список предопределенных кодировок и выбрать тот, который не приводит к ошибкам декодирования, но зависит от входных данных, которые могут соответствовать множеству различных кодировок.
Если вы не знаете заранее кодировку символов, и она отличается для разных платформ, вам нужно как-то проанализировать байтовый массив, чтобы попытаться угадать его. Доступны некоторые алгоритмы обнаружения, но это может быть излишним для вашего приложения.
Можете ли вы настроить свое приложение для получения известного результата? Не нужно быть полной строкой, подойдут только первые символы. Если да, то вы можете сравнить полученный байтовый массив с ожидаемым в различных кодировках и выполнить обнаружение. Массивы байтов UTF8, UTF-16 big и little endian будут отличаться событием для простых строк.
Он должен работать так: если кто-то даст вам файл и скажет, что это UTF-16, они ожидают, что вы изучите первые два байта (BOM), чтобы выяснить, является ли он прямым или младшим. Но если вам сообщают, что кодировка UTF-16LE, значит, нет спецификации; вам это не нужно, потому что они уже сказали вам, что порядок байтов в порядке байтов. Java точно следует этим правилам, что является настоящим недостатком, потому что никто другой этого не делает.
Нативная кодировка символов современных операционных систем Windows - UTF-16, little-endian. К сожалению, отдельные программы не выглядят согласованными, когда дело доходит до меток порядка следования байтов. И вы не можете просто использовать UTF-16LE все время, потому что, если спецификация есть, она будет передана как ненужный символ. Единственный способ узнать заранее, использовать ли UTF-16 или UTF-16LE, - это изучить первые два байта, как описал Макдауэлл.