FileTranslator - работа над ошибками
Ранее я написал статью Как
я писал программу FileTranslator. Программа предназначалась для
транслитерации названий mp3-файлов и предполагалось, что будет
использоваться для формирования файлов для записи на CD и последующего
их воспроизведения на музыкальных центрах. На тех центрах, где есть
функция вывода названия файлов при проигрывании, транслитерированные
названия смотрятся более выигрышно в сравнении с набранными
кириллицей и отображающимися кракозябрами.
Так, суть давней работы я напомнил, пришло время выполнить работу над
ошибками, так как поработать есть над чем.
Для начала переделаем функцию транслитерации. Вместо длиннющего
оператора case, написанного, кроме всего прочего, неправильно, введем
константные строку, состоящую из всех символов русского алфавита, и
массив, содержащий транслитерированные значения.
const
CYRILLIC_SYMBOLS =
'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'
+
'абвгдеёжзийклмнопрстуфхцчшщъыьэюя';
LATIN_SYMBOLS: array[1..66] of String =
('A', 'B', 'V',
'G', 'D', 'E', 'Yo',
'Zh', 'Z', 'I', 'Y',
'K', 'L',
'M', 'N', 'O',
'P', 'R', 'S', 'T',
'U', 'F', 'H', 'Ts',
'Ch', 'Sh',
'Chsh', '''''', 'Y',
'''', 'E', 'Yu', 'Ya',
'a', 'b', 'v',
'g', 'd', 'e', 'yo',
'zh', 'z', 'i', 'y',
'k', 'l',
'm', 'n', 'o',
'p', 'r', 's', 't',
'u', 'f', 'h', 'ts',
'ch', 'sh',
'chsh', '''''', 'y',
'''', 'e', 'yu', 'ya');
function Transliterate(const Source: String): String;
var
I, Index: Integer;
begin
Result := '';
for I := 1 to Length(Source) do
begin
Index := Pos(Source[I], CYRILLIC_SYMBOLS);
if Index > 0 then
Result := Result + LATIN_SYMBOLS[Index]
else
Result := Result + Source[I];
end;
end; |
На вход функции подается строка, на выходе получаем ее
транслитерацию.
Далее, для хранения списка файлов я воспользовался временным
текстовым файлом. Это не совсем правильное решение. Во-первых, нельзя
сказать, что оно достаточно удобно, во-вторых, файловые операции
выполняются медленно (сравнительно с выполняемыми в памяти).
Для хранения списка файлов воспользуемся возможностями класса TStringList.
Напрашивается применение свойств класса Names и Values. В Name-части
поместить исходное имя, в Value – транслитерированное. Проблема в том,
что имя исходного файла может содержать символ "=", что нарушит
работу. Можно поместить имя в кавычки: Windows не разрешает использовать
этот символ в именах файлов, и это снимет проблему, но, с моей точки
зрения, проще применить два объекта класса TStringList. В одном будем
хранить оригинальные названия, в другом – транслитерацию.
Применив всё на практике, получаем такой код программы:
program TransLangCon10_lite;
uses
Classes, SysUtils;
const
CYRILLIC_SYMBOLS =
'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'
+
'абвгдеёжзийклмнопрстуфхцчшщъыьэюя';
LATIN_SYMBOLS: array[1..66] of String =
('A', 'B', 'V',
'G', 'D', 'E', 'Yo',
'Zh', 'Z', 'I', 'Y',
'K', 'L',
'M', 'N', 'O',
'P', 'R', 'S', 'T',
'U', 'F', 'H', 'Ts',
'Ch', 'Sh',
'Chsh', '''''', 'Y',
'''', 'E', 'Yu', 'Ya',
'a', 'b', 'v',
'g', 'd', 'e', 'yo',
'zh', 'z', 'i', 'y',
'k', 'l',
'm', 'n', 'o',
'p', 'r', 's', 't',
'u', 'f', 'h', 'ts',
'ch', 'sh',
'chsh', '''''', 'y',
'''', 'e', 'yu', 'ya');
// Маска поиска файлов .mp3.
MP3_SEARCH_MASK = '*.mp3';
var
SourceFile: TSearchRec;
I: Integer;
SourceNames, TransliteratedNames: TStringList;
// Транслитерировать строку.
function Transliterate(
// Исходная строка.
const Source: String): String;
var
I, Index: Integer;
begin
Result := '';
for I := 1 to Length(Source) do
begin
Index := Pos(Source[I], CYRILLIC_SYMBOLS);
if Index > 0 then
Result := Result + LATIN_SYMBOLS[Index]
else
Result := Result + Source[I];
end;
end;
begin
if FindFirst(MP3_SEARCH_MASK, faAnyFile, SourceFile) = 0 then
try
SourceNames := TStringList.Create;
try
TransliteratedNames := TStringList.Create;
try
repeat
SourceNames.Add(SourceFile.Name);
TransliteratedNames.Add(Transliterate(SourceFile.Name));
until FindNext(SourceFile) <> 0;
for I := 0 to SourceNames.Count - 1 do
if not FileExists(TransliteratedNames[I]) then
RenameFile(SourceNames[I], TransliteratedNames[I]);
finally
TransliteratedNames.Free;
end;
finally
SourceNames.Free;
end;
finally
FindClose(SourceFile);
end;
end. |
Не правда ли, получилось гораздо короче, чем в прошлый раз. Можно еще
вынести процедуру переименования файлов:
// Переименовать файлы.
procedure RenameFiles(
// Список исходных имен файлов.
const FromList: TStringList;
// Список новых имен файлов.
const ToList: TStringList);
var
I: Integer;
begin
for I := 0 to FromList.Count - 1 do
if not FileExists(ToList[I]) then
RenameFile(FromList[I], ToList[I]);
end; |
Программу можно продолжить улучшать. Возможно, в ближайшее время
этим мы и займемся.
Скачать исходник File Translator Lite v.1.1: |
1.42 kB |
Скачать программу File Translator Lite v.1.1: |
48.8 kB |
|