Транслитератор названий mp3-файлов FileTranslatorDelphi , Мультимедиа , АудиоАвтор: Denny С того момента, как подруга приобрела музыкальный центр, читающий диски mp3, мой десктоп стал резать музыкальные болванки в небывалых ранее количествах. Не сразу, но все же всплыл вопрос нормальной записи файлов, названных по-русски, так как центр отказывался читать названия по-русски, выдавая вместо связки "исполнитель-песня" какую-то чушь. Переименовывать "руками" сотню с лишним файлов - обезьянья работа, которую можно произвести однократно из любви к искусству, но не более. Возникло желание автоматизировать процесс, и я задумался как это можно сделать. В этот раз путь от задумки до претворения в жизнь был недолог. В этот же день программа была готова. Ниже я попробую изложить процесс написания программы как можно более полно. Средством решения поставленной задачи была выбрана программа, помещаемая в папку с mp3-файлами (для упрощения программы), предназначенными для копирования на CD, и переименовывающая все файлы, содержащие в названии буквы кириллицы. Все символы кириллицы заменяются на соответствующие им латинские по правилам транслитерации. Так как музыкальный центр читает только названия файлов, но не теги, то с ними морочиться я не счел нужным. Что получилось? Получилось, что программа не получает от пользователя никаких указаний (кроме запуска) и никаких сообщений пользователю не выдает. То есть нет необходимости в каком бы то ни было интерфейсе, что значительно упрощает поставленную задачу и уменьшает размер программы. Распишем алгоритм работы программы. Он прост: перебор файлов в папке и проверка их названий на наличие русских букв, при положительном ответе - переименование. Все. Что ж, приступим. Для начала напишем процедуру переименования. У меня она получилась такой: function Renaming(fn: TSearchRec): string; // Функция переименования файла .mp3 транслитерацией var S: string; i, j: Byte; Ch: Char; begin S := extractfilename(fn.Name); j := Length(S); result := ''; for i := 1 to j do begin Ch := S[i]; case Ch of 'А': result := result + 'A'; 'а': result := result + 'a'; 'Б': result := result + 'B'; 'б': result := result + 'b'; 'В': result := result + 'V'; 'в': result := result + 'v'; 'Г': result := result + 'G'; 'г': result := result + 'g'; 'Д': result := result + 'D'; 'д': result := result + 'd'; 'Е': result := result + 'E'; 'е': result := result + 'e'; 'Ё': result := result + 'Yo'; 'ё': result := result + 'yo'; 'Ж': result := result + 'Zh'; 'ж': result := result + 'zh'; 'З': result := result + 'Z'; 'з': result := result + 'z'; 'И': result := result + 'I'; 'и': result := result + 'i'; 'Й': result := result + 'I'; 'й': result := result + 'i'; 'К': result := result + 'K'; 'к': result := result + 'k'; 'Л': result := result + 'L'; 'л': result := result + 'l'; 'М': result := result + 'M'; 'м': result := result + 'm'; 'Н': result := result + 'N'; 'н': result := result + 'n'; 'О': result := result + 'O'; 'о': result := result + 'o'; 'П': result := result + 'P'; 'п': result := result + 'p'; 'Р': result := result + 'R'; 'р': result := result + 'r'; 'С': result := result + 'S'; 'с': result := result + 's'; 'Т': result := result + 'T'; 'т': result := result + 't'; 'У': result := result + 'U'; 'у': result := result + 'u'; 'Ф': result := result + 'F'; 'ф': result := result + 'f'; 'Х': result := result + 'H'; 'х': result := result + 'h'; 'Ц': result := result + 'Ts'; 'ц': result := result + 'ts'; 'Ч': result := result + 'Ch'; 'ч': result := result + 'ch'; 'Ш': result := result + 'Sh'; 'ш': result := result + 'sh'; 'Щ': result := result + 'Chsh'; 'щ': result := result + 'chsh'; 'Ъ': result := result + '''' + ''''; 'ъ': result := result + '''' + ''''; 'Ы': result := result + 'Y'; 'ы': result := result + 'y'; 'Ь': result := result + ''''; 'ь': result := result + ''''; 'Э': result := result + 'E'; 'э': result := result + 'e'; 'Ю': result := result + 'Yu'; 'ю': result := result + 'yu'; 'Я': result := result + 'Ya'; 'я': result := result + 'ya' else result := result + Ch end end; if FileExists(result) then result := '' // в случае существования файла с таким же именем end; В функцию передается информация о найденном файле. Здесь из него извлекается имя и посимвольно преображается. Результат преображения передается в вызывающую программу. Обратите внимание на последнюю операцию в функции. В ней происходит проверка на существование в папке файла с именем, совпадающим с результатом транслитерации имени другого файла, так как в случае попытки присвоения уже существующего имени происходит фатальная ошибка. Ведь равно возможны две ситуации : переименование файла Queen - Show Must Go On.mp3 в Queen - Show Must Go On.mp3, что глупо, и переименование Секрет - Алиса.mp3 в Sekret - Alisa.mp3 при существовании файла Sekret - Alisa.mp3 , что фатально. Сейчас же и отвечу, почему не переименовывается здесь же. Первоначально новое имя файл обретал здесь же, в функции переименования, но во время тестирования программы в папке с большим количеством файлов, начинался перебор уже переименованных файлов. То есть возникла необходимость разделения во времени процедур перебора и непосредственного переименования. Обратимся теперь к главной программе: var R: TextFile; Renamed: file; S, NewName: string; MusicFile: TSearchRec; i, b: Integer; begin AssignFile(R, 'R.1'); // связываем файловую переменную с временным файлом R.1 if FindFirst('*.mp3', faAnyFile, MusicFile) = 0 then begin Rewrite(R); b := 0; repeat NewName := Renaming(MusicFile); if NewName <> '' then begin inc(b); // считаем mp3-файлы WriteLn(R, NewName); // заносим новое название файла во временный файл WriteLn(R, MusicFile.Name) // заносим старое название файла туда же end until FindNext(MusicFile) <> 0; CloseFile(R); Reset(R); for i := 1 to b do begin ReadLn(R, NewName); ReadLn(R, S); AssignFile(Renamed, S); Rename(Renamed, NewName) end; CloseFile(R); Erase(R); FindClose(MusicFile) end end. Начнем с переменных. R - текстовый файл, куда в процессе работы будут заноситься "старое" и "новое" имена файлов. Файл временный (его название, кстати, выбрано абсолютно случайно), и по окончании работы программы уничтожается. С остальными, думаю, все понятно. Программа перебирает содержимое директории по маске '*.mp3', отбрасывая все "другие" файлы. Как только находится первый подходящий файл, создается временный файл R.1, а сам музыкальный файл "отправляется" на переименование. После перебора всех файлов директории временный файл закрывается и вновь открывается, уже для чтения. Согласно сделанным в нем записям производится переименование. Анализ. Нельзя сказать, что приведенная реализация идеальна. Начнем с того, что если произвести извлечение имени файла в теле программы, и в функцию отправлять уже fn : String, то эту процедуру без значительных преобразований можно использовать в другой программе для транслитерации строк. Спорен также выбор файла для хранения временных данных. Можно для этих же целей воспользоваться динамическим массивом, но это увеличит требования программы к объему оперативной памяти (хотя современные компьютеры не страдают ее недостатком), зато вырастет скорость исполнения (человеку не ощутить разницу) из-за различий времени доступа к постоянной и оперативной памяти. Мало того, можно вообще отказаться от хранения временных данных. Ну и что с того, что программа будет переименовывать уже переименованные файлы? От присвоения файлу его же собственного имени мы себя застраховали, а увеличившееся время работы, повторяю, неощутимо и абсолютно не критично. То есть, размер кода можно значительно сократить, сохранив при этом работоспособность программы, надо только преобразовать функцию Renaming в процедуру. Тогда основная программа будет выглядеть так: var MusicFile: TSearchRec; begin if FindFirst('*.mp3', faAnyFile, MusicFile) = 0 then begin repeat Renaming(MusicFile) until FindNext(MusicFile) <> 0; FindClose(MusicFile) end end. Повторю, необходимо немного переделать функцию Renaming. Например так: procedure Renaming(fn: TSearchRec); var Renamed: file; OldName, NewName: string; i: Byte; Ch: Char; begin OldName := ExtractFileName(fn.Name); for i := 1 to Length(OldName) do begin Ch := OldName[i]; case Ch of 'А': NewName := NewName + 'A'; ... 'я': NewName := NewName + 'ya' else NewName := NewName + Ch end; if not FileExists(NewName) then begin AssignFile(Renamed, OldName); Rename(Renamed, NewName) end end; И наоборот, программу можно усложнить, но тогда появится форма, компоненты, интерфейс и все связанные с этим проблемы, но и восприниматься программа будет совсем иначе. Транслитератор названий mp3-файлов FileTranslator - автоматизированная программа, которая переименовывает файлы в папке, содержащие русские буквы, транслируя их на латиницу. Комментарии и вопросыПолучайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
|
||||
©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007 |