Автор статьи: Сергей Прощаев (@sproshchaev), Руководитель направления Java‑разработки в FinTech
Введение
Многие наверняка сталкивались с ситуацией, когда при открытии файла в текстовом редакторе (например, Word) вместо ожидаемого текста появляется хаотичный набор символов: или «кракозябры». Такое происходит, когда программа неправильно определяет кодировку файла — набор правил, по которым символы преобразуются в двоичный код.
Каждый формат файла (TXT, DOCX, PDF и другие) имеет свою структуру и использует определённую кодировку для хранения данных. Если приложение неверно интерпретирует эти правила, текст становится нечитаемым.
Кодировки или как компьютеры понимают наш язык?
Когда вы печатаете сообщение или читаете статью в интернете, ваш компьютер видит не буквы, а комбинации нулей и единиц. Чтобы превратить эти биты в понятный текст, нужны таблицы кодировок — своего рода «переводчики» между человеческим языком и машинным кодом.
Представьте, что компьютер — это иностранец, который понимает только цифры. Чтобы объяснить ему, что означает буква «А» или символ «!», нужен словарь. Таблица кодировки как раз и является таким словарем: она сопоставляет каждому символу (букве, цифре, эмодзи) уникальный числовой код. Этот код затем преобразуется в байты — минимальные единицы данных, которые компьютер может хранить или передать.
Процесс кодирования состоит из двух шагов.
На первом шаге кодирования символ преобразуется в числовой код. Например, в кодировке ASCII (American Standard Code for Information Interchange) буква A имеет код 65.
Почему 65? Давайте разберемся. В основе этого преобразования лежит система счисления с основанием числа 2 или двоичная система.

Каждая ячейка на рис.1 — это «бит» (0 или 1). Биты соответствуют степеням числа 2: 64 = 2⁶, 32 = 2⁵, 16 = 2⁴, 8 = 2³, 4 = 2², 2 = 2¹, 1 = 2⁰. Как читать двоичное число? Если под числом стоит 1 — оно включено в сумму, если 0 — исключено. На слайде: 64 (2⁶) = 1 → берём 64 32, 16, 8, 4, 2 = 0 → не берём 1 (2⁰) = 1 → берём 1. Теперь складываем выбранные числа: 64 + 1 = 65.
На втором шаге кодирования код 65 преобразуется в последовательность байтов. В ASCII буква A становится байтом 1 000 001. На рис.1 это цифры 1 и 0 красного цвета.
И теперь эти семь бит 1 000 001 мы можем поместить в специальную таблицу, которую называют таблицей кодировок.
Таблицы кодировок
Таблиц кодировок было изобретено множество. Таблица ASCII (American Standard Code for Information Interchange), представленная на рис.2, была создана в 1960-х годах и изначально предназначалась для англоязычных пользователей.

ASCII использует 7 бит данных, что позволяет закодировать всего 128 символов — этого хватает для английского алфавита (заглавные и строчные буквы), цифр, знаков препинания и управляющих команд (например, «перевод строки»). И как раз наша английская буква A, закодированная как 1 000 001 может быть помещена в эту таблицу.
Как в Java можно прочитать и записать произвольную строку символов в файл?
Допустим, мы хотим сохранить фразу «Hello, World!» в файл. Вот как это можно сделать:
import java.io.*;
public class WriteFileDefaultEncoding {
public static void main(String[] args) {
String text = "Hello, World!";
try (Writer writer = new BufferedWriter(
new FileWriter("default_file.txt"))) {
writer.write(text);
System.out.println("Файл записан с кодировкой по умолчанию.");
} catch (IOException e) {
System.out.println("Ошибка: " + e.getMessage());
}
}
}
Как это работает все вместе? FileReader
открывает файл default_file.txt
и пытается прочитать его в кодировке системы. BufferedReader
считывает данные блоками (в данном примере — по 1024 символа за раз). StringBuilder
собирает все считанные части в одну строку, а try‑with‑resources
автоматически закрывает поток после чтения, даже если произошла ошибка.
В этом примере используются классы из пакета java.io
. Класс FileWriter
записывает текст в файл, используя кодировку по умолчанию. Класс BufferedWriter оборачивает FileWriter
для буферизации данных. Использование буферизации увеличивает скорость записи, так как данные сначала накапливаются в памяти (буфере), а затем записываются в файл большими порциями. Writer
представляет собой абстрактный класс, который является базовым для всех классов, записывающих символы в поток. Если произойдёт ошибка (например, файл заблокирован другим процессом), будет выброшено исключение IOException
, и программа выведет сообщение об ошибке.
Теперь выполним обратную операцию и прочитаем файл default_file.txt
, созданный в предыдущем примере, и отобразим его содержимое в консоль:
import java.io.*;
public class ReadFileDefaultEncoding {
public static void main(String[] args) {
try (Reader reader = new BufferedReader(
new FileReader("default_file.txt"))) {
char[] buffer = new char[1024];
int length;
StringBuilder content = new StringBuilder();
while ((length = reader.read(buffer)) != -1) {
content.append(buffer, 0, length);
}
System.out.println("Содержимое файла: " + content.toString());
} catch (IOException e) {
System.out.println("Ошибка: " + e.getMessage());
}
}
}
FileReader
открывает файл default_file.txt
и пытается прочитать его в кодировке системы. BufferedReader
считывает данные блоками (в данном примере — по 1024 символа за раз). StringBuilder
собирает все считанные части в одну строку.
Какие классы используются здесь? FileReader
читает текст из файла, используя кодировку по умолчанию. BufferedReader
оборачивает FileReader
для буферизации данных. Данные, при использовании BufferedReader
считываются большими блоками, а не по одному символу. Reader
это абстрактный класс, базовый для всех классов, считывающих символы из потока.
Заключение
Понимание кодировок — основа работы с текстом в Java и любом другом языке программирования. Кодировки определяют, как символы (буквы, цифры, знаки) преобразуются в двоичный код, который понимает компьютер. Без этого знания даже простые операции — например, чтение файла или вывод строки на экран — могут привести к ошибкам.
Если вы хотите углубить свои знания в области работы с данными, оптимизации процессов или улучшения архитектуры приложений, обратите внимание на следующие открытые онлайн-уроки. Они помогут разобраться в актуальных аспектах технологий и понять, как они применяются в реальных проектах:
27 мая 20:00 — Паттерны RESTful API
28 мая 20:00 — Основы сжатия данных: создаем RLE архиватор
10 июня 20:00 — Журналирование в ОС Linux
Больше актуальных навыков по разработке и работе с данными вы можете получить в рамках практических онлайн-курсов от экспертов отрасли.
Комментарии (5)
kmatveev
21.05.2025 10:33Ужасно. Один из абзацев присутствует в двух местах. Ничего толкового про кодировки не написано.
RomTec
21.05.2025 10:33Очередная статья из серии "Замах - на рубль, удар - на копейку!"
По заголовку предвкушал что-то особенное. Но в статье про обработку "кодировок" вообще не упоминается ... Unicode ! Ну хотя бы про КОИ-8 можно было сказать пару слов ?
skovpen
Задан один вопрос, а ответ на другой вопрос :-)