NodeJS | fs.readdirSync | Вопросы в ромбах вместо русских букв в именах файлов в Debian (Linux)

NodeJS | fs.readdirSync | Вопросы в ромбах вместо русских букв в именах файлов в Debian (Linux)

Работая с файлами в NodeJS, можно столкнуться с проблемой — полученные массивы с именами файлов из директорий сайта(приложения) могут содержать символы «вопроса в ромбе«.

То есть, если у нас файлы на сервере именуются не в латинице, то могут начаться проблемы при переезде сайта в другую систему (на другой хост).

Методы readdir() или readdirSync() могут перестать выдавать корректный результат.

Как это выглядит?

Вопросы в ромбах вместо русских букв на сайте с NodeJS
Вопросы в ромбах вместо русских букв на сайте с NodeJS

 

В чём проблема?

Такая беда неизбежно встретится в Debian (Linux) сервере, если файлы со старого хоста двигаются транзитом в новый хост, через ОС Windows. Радует в этой ситуации только то, что NodeJS тут не причём. NodeJS доверяет операционной системе Debian (Linux) во многих вопросах, поэтому иногда не пытается «умничать» и что-то менять на лету.

Исторически в IT так сложилось, что чем дольше живёт человечество и чем больше появляется новых языков, тем крупнее должна быть «символьная» база, которая хранит в себе все возможные наборы символов разных языков (алфавитов).

Когда всё только начиналось, тогда были только 256 символов — (цифры, латинские буквы, знаки препинания). Этот набор послужил появлению такого понятия как «кодировка«. Каждому символу присваивался свой уникальный числовой код.

Операционных систем становилось больше, кодировок становилось больше. В результате появились проблемы с общением разных систем друг с другом. Нужно было решить проблему на международном уровне.

Сегодня только русский язык застолбил для себя 66 символов своего алфавита. (33 строчные, 33 заглавные). Но есть ещё и другие языки. Появились всякие смайлики, эмодзи и прочее.

Сегодня все символы планеты упакованы в одну систему. Она называется ЮНИКОД. По сути в ЮНИКОДе учли все предыдущие несостыковки. Но…

Но ещё продолжают существовать старые системы, которые участвуют в сетевом обмене файлами в сети интернет. И может оказаться такая нехорошая ситуация, когда какая-то операционная система захочет перекодировать имена файлов к какую-то старую кодировку. И естественно не скажет об этом. В результате разработчик получает неработающее приложение и у него начинает болеть голова от этой проблемы.

 

Решение

Если беда с именами файлов уже случилась, то нужно срочно менять их кодировки на новом хосте. Менять кодировки имён, а не самого содержимого файлов.

Так как Debian (Linux) уже вовсю работает в кодировке UTF-8, то и приводить все имена файлов мы будем к UTF-8. Напомню, что UTF-8 — это часть ЮНИКОДа.

В Debian (Linux) сервере это можно сделать при помощи программы «convmv«:

convmv -r -f cp1251 -t utf-8 /var/www/tabletka.efim360.ru/bad
  • cp1251 Это кодировка из которой хотим сделать UTF-8. Это кодировка, в которую были приведены имена файлов в Windows. Но в вашем случае может быть что-то иное («koi8-r» или «iso-8859-15» или ещё чего)
  • utf-8 Это кодировка, в которую мы приводим имена файлов.
  • /var/www/tabletka.efim360.ru/bad Это путь до директории, в которой лежат файлы с русскими именами в неправильной кодировке

Вызов команды будет выводить потенциальные пути до файлов, а также варианты перекодировки.

Подходящая кодировка для имени файла в Debian Linux для русских символов
Подходящая кодировка для имени файла в Debian Linux для русских символов

 

Мы зрительно наблюдаем за ходом процесса и в конце нам говорится, что изменения не внесены.

Если нас текущая перекодировка устраивает, тогда мы можем выполнить замену «плохой кодировки» на «хорошую кодировку». Для этого просто дописываем в команду выражение «—notest»:

convmv -r --notest -f cp1251 -t utf-8 /var/www/tabletka.efim360.ru/bad

И после этого кодировка имён файлов будет исправлена навечно на новом хосте.

Успешное исправление кодировки имён файлов с cp1251 на utf-8 в Debian 11
Успешное исправление кодировки имён файлов с cp1251 на utf-8 в Debian 11

Мы получаем запись вида: «Ready! I converted 15683 files in 4 seconds.»

Теперь возвращаемся на сайт и перезагружаем страницу.

Корректные имена файлов перешли на страницу сайта
Корректные имена файлов перешли на страницу сайта

 

NodeJS тут же подхватит правильную кодировку из Debian и методы readdir() или readdirSync() смогут корректно заполнить массив строками имён файлов в правильной кодировке с русскими символами.