Вдохновленэтот вопрос, можно ли использовать iconv
команду для генерации выходных данных UTF-16 с BOM и указанным порядком байтов?
Команда iconv
преобразует текст из одной кодировки в другую.
Например:
echo hello | iconv -f ascii -t utf-16
генерирует представление UTF-16 "hello\n"
.
Файлы UTF-16 часто, но не всегда, начинаются с метки порядка байтов (BOM), которая представляет собой 2-байтовую кодировку символа Unicode U+FEFF
. Вы можете определить порядок байтов файла UTF-16 с BOM, проверив, являются ли первые два байта FE FF
или FF FE
.
Команда iconv
имеет несколько опций для генерации выходных данных в формате UTF-16:
$ iconv --list | grep -i utf-16
UTF-16//
UTF-16BE//
UTF-16LE//
Эта команда:
echo hello | iconv -f ascii -t utf-16be
генерирует обратный порядок байтов UTF-16без спецификации; похоже, предполагается, что если вы указали порядок байтов, вам не нужно указывать его в выводе. Аналогично, utf-16le
генерирует little-endian UTF-16 без BOM.
Этот:
echo hello | iconv -f ascii -t utf-16
генерирует (на моей системе x86 Ubuntu) little-endian UTF-16сBOM, но я видел отчет о похожей команде, генерирующей big-endian UTF-16 с BOM, даже в системе с little-endian.
Я всегда могу использовать utf-16be
или utf-16le
и добавить BOM вручную, но я ищу решение, которое просто использует команду iconv
.
Другой обходной путь,еслиВы знаете, что -t utf-16
порождает порядок байтов:
echo hello | iconv -f ascii -t utf-16 | dd conv=swab 2>/dev/null
Что бы я хотелнравитьсяиспользовать что-то вроде:
iconv -f ascii -t utf-16bebom # big-endian with BOM
iconv -f ascii -t utf-16lebom # little-endian with BOM
но iconv
не поддерживает это.
РЕДАКТИРОВАТЬ :
Может ли кто-нибудь, имеющий доступ к системе x86 Mac OSX, опубликовать комментарий, демонстрирующий (скопированный и вставленный) вывод следующей команды?
echo hello | iconv -f ascii -t utf-16 | od -x
решение1
Нет, если указан порядок байтов, iconv
не вставляет BOM.
Это изКонсорциум Unicode
В: Как мне следует поступать с техническими условиями?
О: Вот несколько рекомендаций, которым следует следовать:
- Конкретный протокол (например, соглашения Microsoft для файлов .txt) может потребовать использования BOM для определенных потоков данных Unicode, таких как файлы. Если вам нужно соответствовать такому протоколу, используйте BOM.
- Некоторые протоколы допускают необязательные BOM в случае неразмеченного текста. В таких случаях
- Если известно, что поток текстовых данных является обычным текстом, но имеет неизвестную кодировку, BOM может использоваться в качестве подписи. Если BOM отсутствует, кодировка может быть любой.
- Если поток текстовых данных известен как обычный текст Unicode (но неизвестно, какой порядок байтов), то в качестве подписи можно использовать BOM. Если BOM отсутствует, текст следует интерпретировать как big-endian.
- Некоторые байт-ориентированные протоколы ожидают символы ASCII в начале файла. Если с этими протоколами используется UTF-8, следует избегать использования BOM в качестве подписи формы кодировки.
- Если известен точный тип потока данных (например, Unicode big-endian или Unicode little-endian), BOM использовать не следует. В частности, всякий раз, когда поток данных объявлен как UTF-16BE, UTF-16LE, UTF-32BE или UTF-32LE BOMне должениспользоваться.
(выделено мной)
Я ожидаю, iconv
что он попытается быть верным последнему из этих указаний.
Обновлять.
Отступление
По моему мнению:
Возможность указать спецификацию материалов, безусловно, была бы полезной дополнительной функцией для iconv.
Файл UTF-16LE без BOMявляетсяможно использовать в Windows, хотя иногда и с дополнительными усилиями. Например, диалоговое окно «Открыть файл» в Блокноте позволяет выбрать «Unicode», что является названием Microsoft для «UTF-16LE» и (что неудивительно) похоже, работает с файлами без BOM.
Я могу открыть тестовый файл UTF-16LE (без BOM) или тестовый файл UTF-8 (без BOM) в Блокноте Windows (XP) обычным способом, например, дважды щелкнув имя файла в проводнике. Мне это кажется удобным. Я знаю, что иногда Windows неправильно угадывает кодировку - в этом случае вам придется указать Блокноту кодировку при открытии файла. Это неудобство означает, что включение BOM предпочтительнее для текстовых файлов, предназначенных для использования в Windows.
Если конкретное приложение не будет работать ни с чем, кроме файла UTF-16LE с BOM, то я согласен, что файл UTF-16LE без BOM непригоден для этого конкретного приложения.
Я подозреваю, чтоесливы можете заставить все работать с UTF-8 (без BOM), это лучшее решение в долгосрочной перспективе.
Однако ответ на вопрос "можно ли использовать команду iconv для генерации выходных данных UTF-16 с BOM и указанным порядком байтов?" В настоящее время "Нет".
решение2
Если вы хотите добавить спецификацию в файл, вы можете добавить ее вручную:
Для UTF-8 BOM (EF BB BF)
file='main.cpp'
printf '\xEF\xBB\xBF' > $file.utf8
iconv -f ASCII -t UTF-8 $file >> $file.utf8
mv -v $file.utf8 "converted-$file"
Для UTF-16BE BOM(FE FF)
file='main.cpp'
printf '\xFE\xFF' > $file.utf16be
iconv -f ASCII -t UTF-16BE $file >> $file.utf16be
mv -v $file.utf16be "converted-$file"
Для спецификации UTF-16LE (FF FE)
file='main.cpp'
printf '\xFF\xFE' > $file.utf16le
iconv -f ASCII -t UTF-16LE $file >> $file.utf16le
mv -v $file.utf16le "converted-$file"
Примечание:
Вероятно, вы заметили, что спецификация в каждом случае разная. Вы можете найтибольше информации здесь: