4

У меня есть несколько файлов с именами shift-jis в ANSI. например

home_03@‚¢ƒgƒ‰ƒ“ƒNŠJ‚¢‚½Aƒtƒ@ƒCƒ‹—L‚è 

когда они должны быть в Shift-Jis, как

home_03@青いトランク開いた、ファイル有り

Это потому что архиватор, который я использую, не поддерживает shift-jis. С этим ничего не поделаешь. Но есть ли способ исправить имена файлов файлов, которые я извлек?

редактировать:

другой пример

Ší‹ï‘ä@ƒXƒpƒi

должно быть

器具台@スパナ

1 ответ1

6

Поскольку вы используете Windows, PowerShell, вероятно, самый простой способ.

Теперь PowerShell внутренне использует UTF-16 для своих строк, поэтому преобразование будет включать четыре шага:

  1. Считать неверное имя файла из файловой системы в PS (внутренне представленный в виде строки UTF-16)
  2. Скажите PS преобразовать строку в необработанный байтовый массив, как если бы строка была <неправильная кодировка>. Мы не можем использовать строку PS напрямую (так как это UTF-16).
  3. Скажите PS преобразовать байтовый массив обратно в строку, интерпретирующую его как <правильная кодировка>. Это даст использование строки UTF-16 необработанных байтов, интерпретируемых как Shift-JIS.
  4. Переименовать файл

Давайте начнем с определения кодировок. В вашем случае, я предполагаю, что ваш источник - Windows-1252 (кодовая страница не-Unicode по умолчанию для западной / английской Windows).

$srcEnc = [System.Text.Encoding]::GetEncoding("Windows-1252")
$destEnc = [System.Text.Encoding]::GetEncoding("Shift-JIS")

Вы также можете использовать [System.Text.Encoding]::Default чтобы получить текущую системную кодовую страницу, но я предпочитаю быть явным.

Затем мы применяем шаги преобразования:

$newName = $destEnc.GetString($srcEnc.GetBytes($oldName))

В вашем примере home_03@‚¢ƒgƒ‰ƒ“ƒNŠJ‚¢‚½Aƒtƒ@ƒCƒ‹—L‚è становится home_03@ツいトランク開いたAファイル有り . Хотя это отличается от вашего примера (см. Примечания внизу), оно соответствует тому, что я получаю с http://string-functions.com/encodedecode.aspx's Windows-1252 => Shift-JIS. Если это неверно, возможно, вам придется поиграться, пока не найдете правильные кодировки источника и назначения.

Собираем его вместе со стандартным циклом:

$srcEnc = [System.Text.Encoding]::GetEncoding("Windows-1252")
$destEnc = [System.Text.Encoding]::GetEncoding("Shift-JIS")
Get-ChildItem | %{Rename-Item -LiteralPath "$_" "$($destEnc.GetString($srcEnc.GetBytes($_.Name)))"}

Или, если вы предпочитаете переходить в подкаталоги:

$srcEnc = [System.Text.Encoding]::GetEncoding("Windows-1252")
$destEnc = [System.Text.Encoding]::GetEncoding("Shift-JIS")
Get-ChildItem -Recurse | %{Rename-Item -LiteralPath "$_" "$($destEnc.GetString($srcEnc.GetBytes($_.Name)))"}

Добавьте -File в Get-ChildItem если вы хотите избежать переименования каталогов.


Похоже, ваш пример включает в себя два символа, которые были недопустимы в Windows-1252 и, вероятно, были отброшены при публикации вопроса (на основе изменения процесса с использованием выходных данных вашего примера). Между первыми 144 и 0x90 есть @ (Â), а между 129 и 0x81 - ½ (A). Для удобства всех, кто хочет проверить, вот кодированная версия base64 необработанных байтов: aG9tZV8wM0CQwoKig2eDiYOTg06KSoKigr2BQYN0g0CDQ4OLl0yC6A== .


Также обратите внимание, что это не будет работать, если есть символы, которые Windows считает недействительными в именах файлов вашего источника или назначения. Особенно в имени исходного файла, поскольку ваш инструмент извлечения, вероятно, мог бы безвозвратно исказить имя при извлечении (удалив байты, соответствующие недопустимым символам вроде ? или \ в неправильной кодировке). Единственное, что вы можете сделать в этих случаях, это использовать альтернативный инструмент извлечения, который полностью устраняет эту проблему.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .