thedeemon: (Default)
[personal profile] thedeemon
Один добрый человек поделился архивами, в которых имена файлов были на русском в кодировке UTF-8, что в его ОС в порядке вещей. Когда открываю их своим старым винраром, имена превращаются в мусор типа "01 ¦Э¦-TБTВTА¦-¦¬¦Ж¦¦¦- ¦¬¦-TГ¦¦¦-". Если же распаковываю 7-zip'ом, то гораздо лучше: "01 ╨Э╨░╤Б╤В╤А╨╛╨╕╠Ж╨║╨░ ╨╖╨▓╤Г╨║╨░". В 7-zip есть замечательная опция для задания кодировки, вот только она не работает - что с ней, что без нее получается совершенно одинаково. Решил поискать решение в инете, но мое гугл-фу оказалось недостаточно хорошим. Скачал пару утилит. Первая - какая-то суперпрограмма с описанием на чешском, в которой можно загрузить список файлов и нажать Ок, после чего ровным счетом ничего не происходит. Вторая - сурьезный ренеймер за 50 баксов, умеющий делать с именами файлов абсолютно все кроме того, что мне нужно.
Тогда я решил сделать все сам, в результате получилась такая штука на F#:
#light 
open System.IO 
open System.Text 
 
let conv s = 
  let u16 = Encoding.Unicode 
  let bytes = Encoding.Convert(u16, Encoding.GetEncoding(866), u16.GetBytes(s:string)) 
  Encoding.Convert(Encoding.UTF8, u16, bytes) |> u16.GetString  
   
Directory.GetFiles(".") |> Seq.iter (fun fname -> File.Move(fname, conv fname)) 

Смысл процесса в том, что когда архиватор распаковывает файлы, имя в UTF-8 он считает набором 8-битных символов в текущей кодировке (cp866). Винда же имена файлов хранит в 16-битном юникоде. Программа из юникода получает обратно исходную последовательность байт, трактует ее как UTF-8 и из него уже конвертит в привычный двухбайтный юникод.

Бинарник (4096 байт) можно взять тут.
Это мой самый первый опыт с F#, языка я еще не знаю, наверняка можно сделать лучше.

Отдельный прикол с буквой "й". Похоже, в какой-то из юникодных кодировок она представлена не одной буквой "й", а буквой "и" со значком наверху, навроде немецкого умляута или восточных огласовок. Для неюникодных программ это выглядит как два символа, причем второй какой-то странный. Юникодные программы такие файлы показывают и открывают нормально, а неюникодные затрудняются. Нафига нужно было так изгаляться? В русском алфавите "и" и "й" - разные буквы.

Date: 2009-09-26 07:19 pm (UTC)
From: [identity profile] vorotylo.livejournal.com
Добрый человек уже оповещён о степени своего падения? :)

Date: 2009-10-20 07:24 am (UTC)
From: [identity profile] tonal.myopenid.com (from livejournal.com)
Ежели архив в формате zip, то можно было просто python-ом воспользоваться - у него поддержка zip-файлов искаропки. :)

Date: 2009-10-20 01:52 pm (UTC)
From: [identity profile] thedeemon.livejournal.com
Я на питоне не пишу. Так вышло, что с Руби познакомился раньше, а после него питон кажется сильно некрасивым.

Date: 2009-10-21 03:51 am (UTC)
From: [identity profile] tonal.myopenid.com (from livejournal.com)
А в поставке Руби нет такой либы?
Ну, она тупо гуглом ищется?
http://rubyzip.sourceforge.net/classes/Zip/ZipFile.html

Date: 2009-10-21 04:04 am (UTC)
From: [identity profile] thedeemon.livejournal.com
Либы-то есть, но применить F# было интересней.

Profile

thedeemon: (Default)
Dmitry Popov

December 2025

S M T W T F S
 12 3456
789101112 13
14151617181920
21222324252627
28293031   

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 27th, 2026 10:20 pm
Powered by Dreamwidth Studios