Кодировки текста и символы перевода строки в Windows — основы искажения кодировки и CRLF/LF
· Го Комура · Windows, Кодировки символов, Искажение кодировки, Символы перевода строки, UTF-8, CP932, PowerShell, Unicode
В консультациях о работе с текстом в Windows следующие темы очень часто путаются между собой сразу все вместе.
- В чём разница между
Shift_JISиUTF-8 - Почему возникает искажение кодировки
- В чём разница между
CRLFиLF - Файл перевели в
UTF-8, но почему он всё равно иногда не читается - Почему один и тот же файл выглядит по-разному в редакторе, консоли, Excel и Git
Дело здесь не в сложности японского языка. Почти всегда причина в том, что одна и та же последовательность байт была прочитана с другим предположением о кодировке, либо неверно прочитанное содержимое было сохранено как есть.
К тому же в Windows до сих пор сосуществуют мир Unicode и мир кодовых страниц. Добавьте сюда BOM, символы перевода строки, автоопределение кодировки в редакторе, кодовую страницу консоли и преобразование переводов строк в Git — и тема начинает выглядеть запутанной.
В этой статье мы разберём, с практической точки зрения, часто путаемые в Windows Shift_JIS / UTF-8 / UTF-16, причины возникновения искажения кодировки, разницу между CRLF и LF, а также то, почему эта тема так легко приводит к путанице.
Материал опирается на открытые данные Microsoft Learn, PowerShell, Git, W3C / Unicode по состоянию на апрель 2026 года. Подробности см. в списке источников в конце статьи.
Содержание
- Что важно понять в первую очередь
- Разбираем терминологию
- 2.1 В чём разница между Unicode / UTF-8 / UTF-16 / CP932
- 2.2 Как относиться к
Shift_JISиCP932 - 2.3 Ловушки терминов
ANSI,UnicodeиUTF-8N
- Почему возникает искажение кодировки
- 3.1 Что такое искажение кодировки на самом деле
- 3.2 Искажение отображения и повреждение данных — разные вещи
- 3.3 Приведение к непредставимым символам необратимо
- В чём разница между символами перевода строки
- 4.1
CRLF/LF/CR - 4.2 Перевод строки — вопрос, отдельный от кодировки
- 4.3
\nи байты перевода строки в файле не всегда совпадают
- 4.1
- Почему в Windows особенно легко запутаться
- 5.1 Unicode и устаревшие кодовые страницы сосуществуют
- 5.2 Названия не согласованы
- 5.3 Если текст только ASCII, проблема остаётся незаметной
- 5.4 Содержимое файла, имя файла, консоль и исходный файл — разные уровни
- 5.5 BOM и символы перевода строки действуют по отдельной оси
- 5.6 Инструменты меняют всё сами
- Типичные сценарии сбоев
- Правила, снижающие число сбоев на практике
- Расследование искажения кодировки и различий в переводах строк ведём по этим 5 вопросам
- Итог
- Похожие статьи
- Источники
1. Что важно понять в первую очередь
Если сразу перечислить главное, важны следующие семь пунктов.
- Текстовый файл состоит не из самой строки, а из байт + кодировки + символов перевода строки. Иногда к этому добавляется ещё и BOM.
- Искажение кодировки возникает, когда одни и те же байты декодируются в другой кодировке.
- Проблемы с переводом строки возникают, когда кодировка верна, но не совпадает предположение о разделителе строк.
UnicodeиUTF-8— не одно и то же.Unicodeотносится к набору символов, аUTF-8иUTF-16— это кодировки (encoding).- То, что в Windows называют «
Shift_JIS», на практике безопаснее воспринимать как CP932 / японскую кодовую страницу семейства Windows — так разговор меньше расходится. - Одной фразы «перешли на UTF-8» для спецификации недостаточно. Правилом эксплуатации это становится только тогда, когда решены и наличие BOM, и тип перевода строки.
- Источник путаницы — не сам японский язык, а сосуществование на одной Windows нескольких предположений с разной историей.
При работе с текстом в Windows отправная точка — разделить следующие четыре момента.
- Какие байты содержит этот файл
- В какой кодировке он был записан
- В какой кодировке он был прочитан
CRLFилиLFиспользуется для перевода строки
Уже одно это разделение заметно снижает вероятность запутаться.
2. Разбираем терминологию
2.1 В чём разница между Unicode / UTF-8 / UTF-16 / CP932
Сначала быстрее всего один раз разобрать термины по отдельности.
| Термин | Что обозначает | Пример | Частая путаница |
|---|---|---|---|
| Unicode | Система представления символов в виде номеров | U+3042 (あ) |
Считают тем же самым, что UTF-8 |
| UTF-8 | Кодировка, переводящая Unicode в байты | E3 81 82 |
Считают самим Unicode |
| UTF-16LE | Кодировка, переводящая Unicode в байты | 42 30 |
Путают с пунктом меню «Unicode» |
| CP932 | Устаревшая японская кодовая страница Windows | 82 A0 |
Считают полностью идентичной Shift_JIS |
| CRLF / LF | Байты-разделители строк | 0D 0A / 0A |
Считают разновидностью кодировки |
| BOM | Идентифицирующие байты в начале файла | EF BB BF и т. п. |
Считают названием самой кодировки |
Например, даже для одного символа あ байты различаются в зависимости от кодировки.
Символ: あ
UTF-8 : E3 81 82
CP932 : 82 A0
UTF-16LE : 42 30
Важно понимать: символ и байты — разные вещи. На экране приложение работает с тем, что выглядит как «символы», но при сохранении и передаче в конечном счёте обмен идёт байтами. Сбои чаще всего происходят именно на границе этого преобразования.
2.2 Как относиться к Shift_JIS и CP932
На практике текстовые файлы японской Windows часто огульно называют «Shift_JIS». Для разговора этого достаточно, но для реальной работы такое обозначение немного небрежно.
Если хочется точнее обозначить устаревший японский текст Windows, безопаснее думать о нём как о CP932, или японской кодовой странице семейства Windows.
Если отнестись к этому небрежно, начинаются вот такие расхождения в разговоре.
- Вы сказали «сохрани в
Shift_JIS», а собеседник имел в виду CP932 со стороны Windows - На стороне Linux / macOS файл обработали как
shift_jis, но часть файлов, пришедших из Windows, не воспроизводится корректно - Было сказано «сохранить в
ANSI», но то, какая это кодовая страница, зависело от окружения
Поэтому в спецификациях и заметках при расследовании безопаснее по возможности писать так.
- Не
Shift_JIS, аCP932 - Не
ANSI, аACP (active code page) / в японском окружении обычно CP932 - Не просто
text, а конкретно, напримерUTF-8 no BOM, LF
2.3 Ловушки терминов ANSI, Unicode и UTF-8N
Вокруг Windows источником путаницы становятся и сами словесные обозначения.
Особенно сбивают с толку следующие три.
ANSI— встречается в интерфейсе Windows и в старых описаниях, но это не ASCII. Чаще всего под этим подразумевается активная кодовая страница данной машины.Unicode— в некоторых редакторах и инструментах пункт менюUnicodeна деле означает UTF-16LE. Фраза «сохранил в Unicode» не обязательно означаетUTF-8.UTF-8N— встречается в редакторах, распространённых в японоязычной среде; обычно это лишь ярлык интерфейса для обозначения UTF-8 без BOM, а не официальное название кодировки.
Иными словами, в Windows один и тот же термин у разных инструментов означает разное. Это первая крупная точка путаницы.
3. Почему возникает искажение кодировки
3.1 Что такое искажение кодировки на самом деле
Суть искажения кодировки довольно проста.
- Строка кодируется (encode) в байты в некоторой кодировке
- Эти байты декодируются (decode) обратно в строку в другой кодировке
- Если предположения не совпадают, получается другая строка
Например, если сохранить あ в UTF-8, байты будут такими.
E3 81 82
Если прочитать их как UTF-8, получится あ, а если исходить из предположения CP932 — они будут выглядеть как другая строка, вроде 縺�.
В этом случае повреждён не «японский текст», а предположение о decode.
Если сформулировать искажение кодировки одной строкой, получится так.
Одни и те же байты прочитали как другую кодировку.
3.2 Искажение отображения и повреждение данных — разные вещи
Здесь важно разделять стадию, когда всё ещё можно восстановить, и стадию, когда восстановить уже трудно.
Например, при следующей последовательности действий восстановление ещё возможно.
- Файл в UTF-8 открывают как CP932
- На экране это выглядит как
縺� - Файл ещё не был сохранён
На этой стадии исходные байты по-прежнему остаются в UTF-8. Если заново открыть файл в правильной кодировке, содержимое может восстановиться.
Опасна следующая последовательность действий.
- Файл в UTF-8 неверно читают как CP932
- Содержимое, которое выглядит искажённым, сохраняют как есть
- Исходные байты UTF-8 теряются
На этом этапе речь уже идёт не об искажении отображения, а о повреждении данных.
На практике важно не сводить всё к одной фразе «файл искажён», а как минимум разделять следующие два вопроса.
- Остаются ли сами байты корректными
- Было ли уже пересохранено неверно прочитанное содержимое
3.3 Приведение к непредставимым символам необратимо
Ещё одна опасная ситуация — приведение строки Unicode к узкой кодовой странице вроде CP932.
Если строка содержит символы, отсутствующие в целевой кодировке, происходит одно из следующего.
- Символ заменяется на
? - Вставляется символ-заменитель
- Возникает ошибка преобразования
- Символ заменяется на другой, похожий
Например, некоторые эмодзи и расширенные иероглифы напрямую в CP932 не переводятся. Такой сбой нужно оценивать не по критерию «читается или нет», а по тому, возвращается ли исходное значение после обратного преобразования (round-trip).
Однажды утраченную информацию не восстановить, даже узнав впоследствии правильную кодировку.
4. В чём разница между символами перевода строки
4.1 CRLF / LF / CR
Перевод строки — это тоже байты.
CR= carriage return =0DLF= line feed =0A- В текстовых файлах Windows традиционно используется
CRLF(0D 0A) - В Linux / Unix обычно используется
LF(0A) - Одиночный
CRиногда встречается в старых контекстах вроде классических Mac
В виде таблицы это выглядит так.
| Перевод строки | Байты | Основной контекст |
|---|---|---|
CRLF |
0D 0A |
Традиционные текстовые файлы Windows, устаревшие инструменты |
LF |
0A |
Linux / macOS / большинство инструментов разработки |
CR |
0D |
Довольно старые устаревшие данные |
4.2 Перевод строки — вопрос, отдельный от кодировки
Это довольно важный момент.
Символ перевода строки — вопрос, отдельный от кодировки.
Даже в одном и том же файле UTF-8 перевод строки может быть как CRLF, так и LF.
Например, для содержимого «A, перевод строки, B» байты будут различаться так.
UTF-8 + LF : 41 0A 42
UTF-8 + CRLF : 41 0D 0A 42
То есть вполне обычная ситуация, когда:
UTF-8, но отличается только перевод строкиCP932, но перевод строки —LFUTF-16LE, но перевод строки —CRLF
Поэтому когда говорят «перешли на UTF-8, но всё равно не то», на деле иногда расходится не кодировка, а только перевод строки.
4.3 \n и байты перевода строки в файле не всегда совпадают
Именно здесь программисты незаметно для себя чаще всего путаются.
То, что в исходном коде написано \n, ещё не значит, что в файле обязательно окажется только 0A.
В текстовом режиме (text mode) языка, среды выполнения или I/O API символ \n в Windows иногда преобразуется в CRLF.
То есть возможно расхождение между следующим.
- Представление перевода строки в исходном коде
- Строка во время выполнения
- Байты, сохранённые в файле
- Перевод строки, видимый в редакторе
Из-за этого случаются сбои вроде «я был уверен, что написал LF, но в файле оказался CRLF».
Современные редакторы прекрасно работают с одним лишь LF, но у сопутствующих инструментов, устаревших приложений и бизнес-процессов предположение о CRLF всё ещё сохраняется.
Поэтому проблема перевода строки — не «дела давно минувших дней», она и сегодня регулярно встречается на практике.
5. Почему в Windows особенно легко запутаться
5.1 Unicode и устаревшие кодовые страницы сосуществуют
Это главная причина, по которой в Windows всё так запутано.
В Windows сохраняются оба пути:
- обработка через Unicode
- обработка на основе кодовых страниц
Более новые приложения, веб и кросс-платформенные ресурсы тяготеют к UTF-8, тогда как в старых CSV, TXT, логах, вокруг Excel и в интеграции бизнес-систем сохраняется CP932. Кроме того, в части вывода и вокруг некоторых API вполне обычным делом остаётся и UTF-16LE.
Иными словами, на одной машине с Windows сосуществует сразу несколько текстовых культур.
5.2 Названия не согласованы
Путаницу усиливает не столько сама технология, сколько несогласованность названий.
- Говорят «
Shift_JIS», а по факту это CP932 - Говорят «
ANSI», а по факту это активная кодовая страница - Говорят «
Unicode», а по факту это UTF-16LE - Говорят «
UTF-8», но по факту наличие или отсутствие BOM не определено - Появляются собственные ярлыки редакторов вроде
UTF-8N
Если оставить это без уточнения, разговор внешне выглядит слаженным, но реальное содержание не совпадает.
5.3 Если текст только ASCII, проблема остаётся незаметной
Это тоже значимый фактор.
Поскольку UTF-8 совместим с диапазоном ASCII, файл, содержащий только латинские буквы, цифры и символы, иногда «более-менее читается» даже при неверном предположении о кодировке. На стороне CP932 диапазон, эквивалентный ASCII, тоже редко выглядит искажённым внешне, поэтому проблема не всплывает на поверхность.
В результате складывается такая картина.
- Конфигурационный файл только на английском выглядит без проблем
- Стоит добавить одну строку японского текста, как всё ломается
- Проблема, скрывавшаяся всё это время, впервые проявляется уже в эксплуатации
Поэтому сбои кодировки часто выглядят так, будто «вчера всё работало, а сегодня вдруг сломалось». На деле чаще всего оказывается, что мина была заложена давно, а проявилась она лишь в момент появления не-ASCII символов.
5.4 Содержимое файла, имя файла, консоль и исходный файл — разные уровни
В Windows легко запутаться, если объединить всё нижеперечисленное одним термином «кодировка».
- Имя файла / путь
- Содержимое файла
- Отображение в консоли
- Кодировка самого файла исходного кода
- Формат строк во время выполнения
- Отображение в буфере обмена и элементах GUI
Например, даже если японское имя файла отображается нормально, содержимое самого файла может быть сохранено в CP932. И наоборот: даже если сам файл в UTF-8, при несовпадении кодовой страницы консоли исказится только отображение.
Такие операции, как chcp 65001, в основе своей влияют лишь на предположение на стороне консоли и не меняют байты уже существующего файла.
Более того, даже если файл исходного кода в UTF-8, лог-файл, записываемый во время выполнения, не обязательно окажется тоже в UTF-8. Каждый раз нужно чётко разделять, о кодировке какого именно уровня идёт речь.
Кстати, в японской Windows символ \ иногда отображается как знак иены, и это тоже легко путают с вопросом кодировки.
Однако в большинстве случаев это проблема отображающего шрифта или глифа, а не изменение смысла разделителя пути или экранирующего символа.
5.5 BOM и символы перевода строки действуют по отдельной оси
Одного лишь слова «UTF-8» достаточно только для половины дела.
На практике важны и следующие моменты.
- Есть BOM или нет
CRLFилиLFиспользуется для перевода строки
Например, даже в рамках одного и того же UTF-8:
- есть инструменты Windows, которые читают файл только при наличии BOM
- есть обработка на стороне Unix, где из-за BOM в первом столбце появляются лишние символы
- есть устаревшие инструменты, которым трудно работать с одиночным
LF - при
CRLFмогут портиться shell-скрипты и diff’ы
То есть сбой возможен, даже если кодировка совпадает.
5.6 Инструменты меняют всё сами
Ещё сложнее то, что используемые инструменты меняют содержимое неявно, сами по себе.
- Редактор автоматически определяет кодировку
- При сохранении добавляет или убирает BOM
- Git преобразует
CRLF/LF - Оболочка или команда сохраняет файл в кодировке по умолчанию
- Экспорт CSV использует неожиданную кодовую страницу
- В разных версиях PowerShell и других инструментов различаются значения по умолчанию
То есть даже если исполнитель ничего явно не указывал, на практике в Windows какой-то из слоёв сам добавляет своё предположение.
Это и есть истинная причина ситуации «я ничего не менял, а всё сломалось». На деле нередко меняет не человек, а значения по умолчанию инструмента.
6. Типичные сценарии сбоев
Типичные сбои в виде таблицы выглядят так.
| Ситуация | Что на самом деле расходится | Типичный симптом |
|---|---|---|
Устаревший инструмент Windows принимает конфигурационный файл UTF-8 no BOM за ANSI / CP932 |
Предположение о decode | Искажается только японский текст |
| CSV в CP932 передают в систему, работающую по предположению UTF-8 | Предположение о decode | �, ошибка decode, бессмысленный японский текст |
| Лог в UTF-16LE передают в текстовый инструмент Unix | Предположение о кодировке | Примешиваются NUL-байты, файл выглядит как бинарный |
Файл исходного кода в LF в другом окружении преобразуют в CRLF |
Предположение о переводе строки | Огромный diff по концам строк, сбои в скриптах |
| Неверно прочитанное содержимое сохраняют как есть | Сами байты превращаются в нечто иное | Необратимое повреждение данных |
| В спецификации написано только «выгрузить CSV» | Интерфейс не определён | Excel читает, а другой инструмент ломается |
| Решили лишь «унифицировать на UTF-8» | BOM / перевод строки не определены | Не срабатывают только отдельные инструменты |
Особенно опасен сценарий, при котором увидев искажённое отображение, содержимое сохраняют как есть, тем самым окончательно закрепляя сбой.
7. Правила, снижающие число сбоев на практике
Далее речь пойдёт о том, какие правила эксплуатации стоит определить, чтобы снизить число сбоев.
7.1 Определяем базовый вариант для новых файлов
Для новых файлов разумно в первую очередь выбирать UTF-8 в качестве базового варианта. Но одного этого недостаточно.
Как минимум безопаснее определить ещё и следующее.
UTF-8 with BOMилиUTF-8 no BOMCRLFилиLFдля перевода строки- Кто будет читать этот файл
- Нужна ли совместимость с устаревшими инструментами Windows
- Будут ли читать файл также Linux / macOS / CI / контейнеры
Например, для исходного кода и конфигурации, рассчитанных на кросс-платформенность, первым кандидатом обычно становится UTF-8 no BOM + LF. С другой стороны, если нужно подстроиться под старые инструменты Windows или существующую эксплуатацию, иногда всё ещё необходимы UTF-8 with BOM или CP932 + CRLF.
Важно принимать решение исходя не из общих рассуждений «что правильно», а из того, с кем именно происходит обмен данными.
7.2 Не меняем существующие legacy-файлы по своей инициативе
Если существующий файл в CP932, безопаснее не переводить его в UTF-8 заодно с повседневной небольшой правкой.
Безопасная схема эксплуатации выглядит так.
- Существующие файлы сохраняют исходную кодировку / BOM / перевод строки
- Преобразование кодировки выделяется в отдельную задачу миграции
- Массовое преобразование выполняется только после проверки объектов конвертации и downstream-потребителей
Сбои с искажением кодировки нередко начинаются с благих намерений — «заодно модернизировать».
7.3 Рассматриваем кодировку и перевод строки как часть интерфейса
Для CSV, TXT, логов, конфигурационных файлов и простых протоколов интерфейсом является не только содержимое, но и сам формат текста.
В спецификации безопаснее указать как минимум следующее.
- Кодировка
- Наличие BOM
- Тип перевода строки
- Наличие заголовка
- Правила экранирования / разделителя
- Каким инструментом проводилась проверка
Например, одних лишь трёх букв CSV недостаточно.
Только когда написано UTF-8 with BOM, CRLF, разделитель — запятая, с заголовком, разговор перестаёт расходиться.
7.4 Явно указываем кодировку на границах чтения и записи
На стороне кода тоже безопаснее не полагаться на неявные значения по умолчанию.
- При чтении / записи файла явно указывать кодировку
- Учитывать кодировку и при передаче текста между процессами
- В процедурах экспорта / импорта фиксировать в спецификации и перевод строки
- Не делать небрежное перенаправление оболочки продуктивным путём передачи данных
Особенно в Windows «удалось сохранить» и «сохранилось с правильными байтами» — не одно и то же.
7.5 Делимся правилами Git и редактора
Git — не инструмент, который автоматически исправляет кодировку. При этом для line endings преобразование иногда всё же происходит.
Поэтому безопаснее определить следующее на уровне репозитория.
- Использовать ли
LFкак основной вариант для исходного кода - Допускать ли
CRLFдля текста, предназначенного только для Windows - Как зафиксировать это в
.gitattributes - Как делиться настройками редактора
Важно рассматривать кодировку и line endings отдельно друг от друга. Даже если Git приводит переводы строк к единому виду, сбои с кодировкой никуда не денутся.
7.6 Не останавливаемся на «файл искажён» — говорим, что именно разошлось
На практике хорошо помогает такая замена формулировок.
- Плохая формулировка: «файл искажён»
- Хорошая формулировка: «похоже, файл UTF-8 no BOM открывают с предположением CP932»
- Плохая формулировка: «с концами строк что-то не так»
- Хорошая формулировка: «файл в LF преобразуется в CRLF, из-за чего растёт diff»
Уже одна лишь способность назвать, что именно разошлось, заметно ускоряет расследование.
8. Расследование искажения кодировки и различий в переводах строк ведём по этим 5 вопросам
Если расследование зашло в тупик, быстрее всего вернуться к следующим пяти вопросам.
- Какие байты сейчас содержит этот файл
- Это UTF-8?
- UTF-8 с BOM?
- CP932?
- UTF-16LE?
- Кто и с каким предположением записал файл первым
- Редактор?
- Устаревшее приложение?
- Экспорт из Excel?
- Оболочка / скрипт?
- Batch-процесс / промежуточное ПО?
- Кто и с каким предположением читает файл сейчас
- Автоопределение редактора?
- Кодовая страница консоли?
- Кодировка по умолчанию в библиотеке?
- Спецификация на стороне импорта?
- Что представляют собой BOM и перевод строки
- BOM есть или нет
CRLFилиLF
- Было ли уже сохранено неверно прочитанное содержимое
- Это пока только отображение?
- Или файл уже пересохранён и байты утрачены?
Когда ответы на эти пять вопросов найдены, причина, как правило, становится видна.
9. Итог
Кодировки и символы перевода строки в Windows выглядят запутанными не потому, что сложен сам японский язык. Причина в том, что байты, кодировка, BOM, перевод строки и значения по умолчанию инструментов существуют независимо друг от друга, а вдобавок в Windows сосуществуют старая и новая текстовые культуры.
Особенно стоит запомнить следующие шесть пунктов.
- Искажение кодировки — результат чтения одних и тех же байт в другой кодировке
- Проблема перевода строки лежит в плоскости, отдельной от кодировки
- Не стоит слишком доверять словам
Shift_JIS,CP932,ANSI,Unicodeбуквально - Одной фразы «перешли на UTF-8» недостаточно, нужны ещё BOM и тип перевода строки
- Искажение отображения и уже сохранённое повреждение данных нужно рассматривать раздельно
- В спецификации писать не просто
text, а конкретно, напримерUTF-8 no BOM, LF
Иными словами, при работе с текстом в Windows практичнее считать это не «вопросом строк», а вопросом того, как согласовать договорённость о байтах.
10. Похожие статьи
- Разбираемся с кодировками текста в Windows — почему возникает искажение кодировки и что расходится при интеграции с Linux
- Лучшие практики снижения числа сбоев кодировки у Codex в Windows — сначала решаем «как давать инструкции», а не донастраиваем окружение
11. Источники
- Microsoft Learn, Code Page Identifiers - Win32 apps https://learn.microsoft.com/en-us/windows/win32/intl/code-page-identifiers
- Microsoft Learn, about_Character_Encoding - PowerShell https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_character_encoding?view=powershell-7.6
- Microsoft Learn, Understanding file encoding in VS Code and PowerShell https://learn.microsoft.com/en-us/powershell/scripting/dev-cross-plat/vscode/understanding-file-encoding?view=powershell-7.6
- W3C Internationalization, Character encodings: Essential concepts https://www.w3.org/International/articles/definitions-characters/
- Git documentation, gitattributes https://git-scm.com/docs/gitattributes
- Git documentation, git-config https://git-scm.com/docs/git-config
Похожие статьи
Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.
Введение в кодировки текста в Windows — искажение кодировки (mojibake), возникающее при интеграции с Linux
Разбираем практические причины искажения кодировки в Windows — через различия между CP932, UTF-8, UTF-16, BOM, кодовыми страницами, Power...
Правила промптинга, которые снижают число сбоев кодировки текста у Codex в Windows
Разбираем практические правила промптинга для работы Codex с японоязычными файлами в Windows: как не давать сохранять файл «на угадай», с...
Обработка ошибок и повторные попытки в PowerShell — от ловушки нерабочего try/catch до exit code и типовых схем повтора
Разбираем на практике различия между завершающими и незавершающими ошибками в PowerShell, ловушку неработающего try/catch и приём -ErrorA...
Политика выполнения PowerShell и подпись скриптов — практическое руководство, как перестать «затыкать дыры» параметром Bypass
Политика выполнения PowerShell — это «не граница безопасности, а защитный механизм». Разбираем различия между RemoteSigned и другими поли...
Задачи планировщика заданий Windows не запускаются или завершаются с 0x1 — диагностика причин и проектирование надёжного выполнения по расписанию
Разбираем принципы проектирования надёжного выполнения задач по расписанию в Windows: учётные записи выполнения и типы входа в систему, т...
Связанные темы
Эти страницы показывают тему статьи в более широком контексте услуг и решений.
Технические темы Windows
Раздел о разработке Windows, расследовании сбоев и использовании существующих активов.
Услуги по этой теме
Статья напрямую связана со следующими услугами.
Технические консультации и ревью дизайна
В проектах, где предположения о кодировке CSV, логов и конфигурационных файлов расходятся между Windows и Linux, заблаговременное упорядочивание I/O-контракта и правил эксплуатации помогает снизить число инцидентов.
Разработка приложений для Windows
В бизнес-инструментах для Windows часто встречается смешение CP932 и UTF-8, поэтому продуманная работа с кодировками и символами перевода строки на этапе проектирования напрямую влияет на сопровождаемость.
Частые вопросы
Вопросы, которые часто возникают при консультациях по теме статьи.
- Почему возникает искажение кодировки?
- Потому что одна и та же последовательность байт была прочитана в кодировке, отличной от той, в которой она была записана. Например, если сохранить символ «あ» в UTF-8, получится последовательность байт E3 81 82, но при чтении в контексте CP932 она превратится в другую строку вроде «縺». В этом случае повреждён не японский текст, а предположение о decode. При этом если сохранить неверно прочитанное содержимое поверх исходного файла, исходные байты будут утрачены, и это станет уже не искажением отображения, а повреждением данных — поэтому важно переоткрыть файл в правильной кодировке ещё до сохранения.
- В чём разница между CRLF и LF?
- Это разница в байтах, которыми обозначается разделитель строк. CRLF — это два байта 0D 0A, традиционно используемые в текстовых файлах Windows, а LF — один байт 0A, распространённый в Linux / macOS и большинстве инструментов разработки. Важно понимать, что перевод строки — это вопрос, отдельный от кодировки: в одном и том же файле UTF-8 перевод строки может быть как CRLF, так и LF, поэтому фраза «перешли на UTF-8, но всё равно не то» иногда означает, что разошлась не кодировка, а только тип перевода строки.
- Shift_JIS и CP932 — это одно и то же?
- Для разговора этого достаточно, но на практике безопаснее их различать. Если хочется точнее обозначить устаревший японский текст Windows, лучше думать о нём как о CP932 или о японской кодовой странице семейства Windows. Аналогично, обозначение «ANSI» в Windows чаще всего означает активную кодовую страницу данной машины, а пункт меню «Unicode» в некоторых редакторах на деле означает UTF-16LE. В спецификациях и заметках при расследовании стоит писать конкретно, например «UTF-8 no BOM, LF», а не расплывчатые названия.
- Что нужно зафиксировать в спецификации текстового файла?
- Одной фразы «перешли на UTF-8» недостаточно — правилом эксплуатации это становится только тогда, когда решены ещё и наличие BOM, и тип перевода строки. Для файлов обмена вроде CSV и логов безопаснее прописать вплоть до кодировки, наличия BOM, перевода строки, наличия заголовка и правил разделителя. Для исходного кода и конфигурации, рассчитанных на кросс-платформенность, первым кандидатом обычно становится UTF-8 no BOM + LF, а если нужно подстроиться под старые инструменты Windows, иногда всё ещё необходимы UTF-8 with BOM или CP932 + CRLF.
Об авторе
Страница с профилем автора статьи.
Го Комура
Представитель KomuraSoft LLC
Специализируется на разработке программного обеспечения для Windows, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.
Публичные ссылки