Вход/Регистрация
Excel. Трюки и эффекты
вернуться

Гладкий Алексей Анатольевич

Шрифт:

Преобразование из абсолютного в относительный путь и наоборот продемонстрировано на рис. 4.4 (нижняя часть формы). При этом в качестве исходного пути берется содержимое текстового поля Исходный длинный путь, а в качестве пути папки для построения относительного пути – содержимое поля Текущая папка.

Рис. 4.4. Преобразование путей

На всякий случай нужно уточнить, что в относительном пути элемент. указывает на текущую папку (никуда переходить не надо), а элемент. означает папку, расположенную на один уровень выше (родительскую папку). Также следует уточнить, что под абсолютным путем понимается путь, корневым элементом которого является \\ или <диск>: \ (С: \, D: \ их д.).

...

Примечание

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

Преобразование длинных имен файлов в короткие и наоборот

Теперь рассмотрим реализацию преобразования путей. Сначала – преобразование между длинной и короткой формами. Выполняется это предельно просто, благо Windows API предусматривает соответствующие функции.

Преобразование длинного пути в короткий приводится в листинге 4.17.

...

Листинг 4.17.

Преобразование пути из длинной в короткую форму

function LongPathToShort(path: String): String;

var

buffer: String;

len: Integer;

begin

SetLength(buffer, MAX_PATH);

len := GetShortPathName(PAnsiChar(path), PAnsiChar(buffer),

MAX_PATH);

SetLength(buffer, len);

LongPathToShort := buffer;

end;

Соответственно, обратное преобразование пути может выглядеть следующим образом (листинг 4.18).

...

Листинг 4.18.

Преобразование пути из короткой в длинную форму

function ShortPathToLong(path: String): String;

var

buffer: String;

len: Integer;

begin

SetLength(buffer, MAX_PATH);

len := GetLongPathName(PAnsiChar(path), PAnsiChar(buffer),

MAX_PATH);

SetLength(buffer, len);

ShortPathToLong := buffer;

end;

При тестировании последнего листинга в Delphi 7 выяснилось, что API-функция GetLongPathName объявлена в модуле Windows. Возможно, в более старых или новых версиях Delphi это не так. Но в любом случае импортировать эту функцию из библиотеки Kernel32. dll предельно просто, достаточно поместить в модуль следующую строку:

...

function GetLongPathName(lpszLongPath: PChar;

lpszShortPath: PChar; cchBuffer: DWORD): DWORD;

stdcall; external kernel32 name \'GetLongPathNameA\

Преобразование абсолютного пути в относительный и наоборот

Теперь пришла очередь рассмотреть реализацию преобразований между абсолютной и относительной формами путей. Однако сначала рассмотрим небольшую, но полезную процедуру, используемую при преобразованиях. Процедура GetPathElements (листинг 4.19) формирует список строк из компонентов переданного ей пути (имен каталогов и имени целевого файла или каталога).

...

Листинг 4.19.

Разбиение пути на составляющие

procedure GetPathElements(path: String; elements: TStrings);

var

start, pos: Integer;

begin

start := 1;

for pos := 1 to Length(path) do

if path[pos] = \'\\' then

begin

if start <> pos then

//Выделим имя каталога

elements.Add(Copy(path, start, pos – start))

else

//Сочетание типа \'\\\' в середине пути пропускаем

;

start := pos + 1;

end;

pos := Length(path) + 1;

if start <> pos then

//Выделим имя последнего каталога или файла

elements.Add(Copy(path, start, pos – start));

end;

После применения процедуры GetPathElements работать с компонентами пути становится очень удобно, да к тому же и упрощается код функций преобразования, так как при их написании не нужно уделять внимание правильному выделению подстрок из строки полного пути.

Функция преобразования абсолютного пути в относительный (от заданной в параметре curdir папки) приводится в листинге 4.20.

...

Листинг 4.20.

Преобразование абсолютного пути в относительный

function AbsPathToRelative(path, curdir: String): String;

var

pathElements, curElements: TStrings;

outPath: String;

i, j: Integer;

begin

if Copy(path, 1, 2) <> Copy(curdir, 1, 2) then

begin

//Папки на разных дисках

AbsPathToRelative := path;

Exit;

end;

//Получение составляющих абсолютного и текущего пути

pathElements := TStringList.Create;

GetPathElements(path, pathElements);

curElements := TStringList.Create;

GetPathElements(curdir, curElements);

//Пропускаем одинаковые папки

i := 0;

while (i < curElements.Count) and (i < pathElements.Count)

and (CompareText(curElements[i], pathElements[i]) = 0) do Inc(i);

//Добавляем небходимое количество переходов вверх для того,

//чтобы из папки curdir попасть в общую для path и curdir папку

for j := i to curElements.Count-1 do

outPath := outPath + \'..\\

//Заходим из папки полученной (общей) папки в папку path

for j := i to pathElements.Count – 2 do

outPath := outPath + pathElements[j] + \'\\

//Последним добавляем имя конечной папки или файла

AbsPathToRelative := outPath + pathElements[pathElements.Count – 1];

//Списки строк больше не нужны

pathElements.Free;

curElements.Free;

end;

При преобразовании нужно учитывать, что пути, не принадлежащие одной иерархии (например, локальный и сетевой или пути, принадлежащие разным дискам, не могут быть представлены один относительно другого: у них нет общего родительского каталога.

Обратное преобразование относительного пути в абсолютный приведено в листинге 4.21. Здесь нужно отметить, что если путь папки curdir относительный, то в итоге получим также относительный путь (только относительно другой папки). Поэтому функция и называется RelativePathToRelative, а не RelativePathToAbs.

  • Читать дальше
  • 1
  • ...
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: