std.path

Переместиться к: absolutePath · asAbsolutePath · asNormalizedPath · asRelativePath · baseName · buildNormalizedPath · buildPath · CaseSensitive · chainPath · defaultExtension · dirName · dirSeparator · driveName · expandTilde · extension · filenameCharCmp · filenameCmp · globMatch · isAbsolute · isDirSeparator · isRooted · isValidFilename · isValidPath · pathSeparator · pathSplitter · relativePath · rootName · setExtension · stripDrive · stripExtension · withDefaultExtension · withExtension

Этот модуль используется для манипуляции строками путей к файлам.
Все функции, за исключением expandTilde (и, в некоторых случаях, absolutePath и relativePath), являются чистыми функциями, предназначенными для манипуляции над строками; они не зависят от какого-либо состояния вне программы и не выполняют никаких реальных действий над файловой системой. Это приводит к тому, что модуль не делает различий между путём, указывающим на каталог, и путём, указывающим на файл, и не знает, действительно ли объект, на который указывает путь, существует в файловой системе. Чтобы различать эти случаи, используйте std.file.isDir и std.file.exists.
Обратите внимание, что в Windows как обратная косая черта (\), так и прямая косая черта (/) в принципе являются допустимыми разделителями каталогов. Этот модуль считает их равноправными, но в случае добавления нового разделителя будет использоваться обратная косая черта. Кроме того, функция buildNormalizedPath заменит на этой платформе все прямые слэши на обратную косую черту.
В общем случае, функции этого модуля предполагают, что входные пути правильно сформированы. (То есть они не должны содержать недопустимые символы, они должны следовать формату путей файловой системы и т. д.). Результат вызова функции на неверно сформированном пути не определён. Если существует вероятность того, что путь или имя файла окажутся ошибочными (например, когда их вводит пользователь), иногда бывает желательно использовать функции isValidFilename и isValidPath для их проверки.
Большинство функций не выполняют никаких распределений памяти, и если возвращается строка, она обычно является срезом входной строки. Если всё-же функция выделяет память, это явно упоминается в документации.

Обновление: digitalmars.com/d/1.0/phobos/std_path.html#fnmatch можно заменить на globMatch.

Авторы:
Lars Tandle Kyllingstad, Walter Bright, Grzegorz Adam Hankiewicz, Thomas Kühne, Andrei Alexandrescu
Лицензия:
Boost License 1.0

Исходный код: std/path.d

enum string dirSeparator;
Строка, используемая для разделения имен каталогов в пути. Под POSIX это прямая косая черта, под Windows – обратная косая черта.
enum string pathSeparator;
Строка разделителя путей. Двоеточие под POSIX, точка с запятой под Windows.
pure nothrow @nogc @safe bool isDirSeparator(dchar c);
Определяет, является ли данный символ разделителем каталогов.
В Windows сюда включается как \, так и /. На POSIX это только /.

Переместиться к: no · osDefault · yes

enum CaseSensitive: bool;
Это перечисление используется как аргумент шаблона для функций, которые сравнивают имена файлов, и служит для определения, является ли сравнение чувствительным к регистру или нет.
no
Имена файлов не чувствительны к регистру
yes
Имена файлов чувствительны к регистру
osDefault
Значение по умолчанию (или общепринятое) для текущей платформы. То есть, no в Windows и Mac OS X, и yes на всех POSIX-системах, кроме OS X (Linux, * BSD и т.д.).
auto baseName(R)(R path)
if (isRandomAccessRange!R && hasSlicing!R && isSomeChar!(ElementType!R) || is(StringTypeOf!R));

pure @safe inout(C)[] baseName(CaseSensitive cs = CaseSensitive.osDefault, C, C1)(inout(C)[] path, in C1[] suffix)
if (isSomeChar!C && isSomeChar!C1);
Параметры:
cs Будет или нет suffix соответствовать с учетом регистра. Whether or not suffix matching is case-sensitive.
R path Имя пути. Это может быть строка или диапазон символов с произвольным доступом.
C1[] suffix Необязательный суффикс, который нужно удалить из имени файла.
Возвращает:
Имя файла в имени пути, без какого-либо ведущего каталога и без необязательного суффикса.
Если указан suffix, сравнение с path будет проводиться с использованием filenameCmp!cs, где cs является необязательным параметром шаблона, определяющим, является ли сравнение чувствительным к регистру или нет. Подробнее см. документацию filenameCmp.

Пример:

assert (baseName("dir/file.ext")         == "file.ext");
assert (baseName("dir/file.ext", ".ext") == "file");
assert (baseName("dir/file.ext", ".xyz") == "file.ext");
assert (baseName("dir/filename", "name") == "file");
assert (baseName("dir/subdir/")          == "subdir");

version (Windows)
{
    assert (baseName(`d:file.ext`)      == "file.ext");
    assert (baseName(`d:\dir\file.ext`) == "file.ext");
}

Замечание: Эта функция удаляет только указанный суффикс, который необязательно должен представлять собой расширение. Чтобы удалить расширение из пути, независимо от того, какое именно это расширение, используйте функцию stripExtension. Чтобы получить имя файла без ведущих каталогов и без расширения, объедините функции следующим образом:

assert (baseName(stripExtension("dir/file.ext")) == "file");

Стандарты:
Эта функция соответствует требованиям POSIX для утилиты оболочки 'basename' (с соответсвующими адаптациями для путей в Windows).
auto dirName(R)(R path)
if ((isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) || isNarrowString!R) && !isConvertibleToString!R);
Возвращает часть пути с каталогом. В Windows она включает в себя букву диска, если эта буква присутствует.
Параметры:
R path Имя с путём.
Возвращает:
Кусочек пути или ".".
Стандарты:
Эта функция соответствует требованиям POSIX для утилиты оболочки 'dirname' (с соответсвующими адаптациями для путей в Windows).
Примеры:
assert (dirName("") == ".");
assert (dirName("file"w) == ".");
assert (dirName("dir/"d) == ".");
assert (dirName("dir///") == ".");
assert (dirName("dir/file"w.dup) == "dir");
assert (dirName("dir///file"d.dup) == "dir");
assert (dirName("dir/subdir/") == "dir");
assert (dirName("/dir/file"w) == "/dir");
assert (dirName("/file"d) == "/");
assert (dirName("/") == "/");
assert (dirName("///") == "/");

version (Windows)
{
    assert (dirName(`dir\`) == `.`);
    assert (dirName(`dir\\\`) == `.`);
    assert (dirName(`dir\file`) == `dir`);
    assert (dirName(`dir\\\file`) == `dir`);
    assert (dirName(`dir\subdir\`) == `dir`);
    assert (dirName(`\dir\file`) == `\dir`);
    assert (dirName(`\file`) == `\`);
    assert (dirName(`\`) == `\`);
    assert (dirName(`\\\`) == `\`);
    assert (dirName(`d:`) == `d:`);
    assert (dirName(`d:file`) == `d:`);
    assert (dirName(`d:\`) == `d:\`);
    assert (dirName(`d:\file`) == `d:\`);
    assert (dirName(`d:\dir\file`) == `d:\dir`);
    assert (dirName(`\\server\share\dir\file`) == `\\server\share\dir`);
    assert (dirName(`\\server\share\file`) == `\\server\share`);
    assert (dirName(`\\server\share\`) == `\\server\share`);
    assert (dirName(`\\server\share`) == `\\server\share`);
}
auto rootName(R)(R path)
if ((isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) || isNarrowString!R) && !isConvertibleToString!R);
Возвращает корневой каталог указанного пути или null, если в пути отсутствует корень.
Параметры:
R path Имя с путём.
Возвращает:
Кусочек пути.
Примеры:
assert (rootName("") is null);
assert (rootName("foo") is null);
assert (rootName("/") == "/");
assert (rootName("/foo/bar") == "/");

version (Windows)
{
    assert (rootName("d:foo") is null);
    assert (rootName(`d:\foo`) == `d:\`);
    assert (rootName(`\\server\share\foo`) == `\\server\share`);
    assert (rootName(`\\server\share`) == `\\server\share`);
}
auto driveName(R)(R path)
if ((isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) || isNarrowString!R) && !isConvertibleToString!R);
Получить часть пути, представляющую диск.
Параметры:
R path Строка или диапазон символов
Возвращает:
Кусочек пути, который является диском, или пустой диапазон, если диск не указан. В случае UNC-путей возвращается сетевой ресурс.
В POSIX всегда возвращает пустой диапазон.
Примеры:
version (Posix)  assert (driveName("c:/foo").empty);
version (Windows)
{
    assert (driveName(`dir\file`).empty);
    assert (driveName(`d:file`) == "d:");
    assert (driveName(`d:\file`) == "d:");
    assert (driveName("d:") == "d:");
    assert (driveName(`\\server\share\file`) == `\\server\share`);
    assert (driveName(`\\server\share\`) == `\\server\share`);
    assert (driveName(`\\server\share`) == `\\server\share`);

    static assert (driveName(`d:\file`) == "d:");
}
auto stripDrive(R)(R path)
if ((isRandomAccessRange!R && hasSlicing!R && isSomeChar!(ElementType!R) || isNarrowString!R) && !isConvertibleToString!R);
Удаляет диск из пути в Windows. В POSIX путь возвращается без изменений.
Параметры:
R path Имя с путём
Возвращает:
Кусочек пути без компонента, представляющего диск.
Примеры:
version (Windows)
{
    assert (stripDrive(`d:\dir\file`) == `\dir\file`);
    assert (stripDrive(`\\server\share\dir\file`) == `\dir\file`);
}
auto extension(R)(R path)
if (isRandomAccessRange!R && hasSlicing!R && isSomeChar!(ElementType!R) || is(StringTypeOf!R));
Параметры:
R path Имя с путём.
Возвращает:
Расширение из имени файла, включает точку.
Если расширение отсутствует, возвращается null.
Примеры:
assert (extension("file").empty);
assert (extension("file.") == ".");
assert (extension("file.ext"w) == ".ext");
assert (extension("file.ext1.ext2"d) == ".ext2");
assert (extension(".foo".dup).empty);
assert (extension(".foo.ext"w.dup) == ".ext");

static assert (extension("file").empty);
static assert (extension("file.ext") == ".ext");
auto stripExtension(R)(R path)
if ((isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) || isNarrowString!R) && !isConvertibleToString!R);
Удалить расширение из пути.
Параметры:
R path Строка или диапазон для разделения
Возвращает:
Срез пути path, у которого удалено расширение (если оно было).
Примеры:
assert (stripExtension("file")           == "file");
assert (stripExtension("file.ext")       == "file");
assert (stripExtension("file.ext1.ext2") == "file.ext1");
assert (stripExtension("file.")          == "file");
assert (stripExtension(".file")          == ".file");
assert (stripExtension(".file.ext")      == ".file");
assert (stripExtension("dir/file.ext")   == "dir/file");
immutable(Unqual!C1)[] setExtension(C1, C2)(in C1[] path, in C2[] ext)
if (isSomeChar!C1 && !is(C1 == immutable) && is(Unqual!C1 == Unqual!C2));

immutable(C1)[] setExtension(C1, C2)(immutable(C1)[] path, const(C2)[] ext)
if (isSomeChar!C1 && is(Unqual!C1 == Unqual!C2));
Параметры:
C1[] path A path name
C2[] ext The new extension
Возвращает:
Строка, содержащая путь, полученный из данного path, у которого расширение установлено в ext.
Если имя файла уже имеет расширение, оно заменяется. Если нет, расширение просто добавляется к имени файла. Включение ведущей точки в ext необязательно.
Если расширение ext пустое, эта функция эквивалентна stripExtension.
Эта функция обычно выделяет новую строку (за исключением случая, когда путь path является immutable и уже не имеет расширения).
Смотрите также:
withExtension, которая не распределяет память и возвращает ленивый диапазон.
Примеры:
assert (setExtension("file", "ext") == "file.ext");
assert (setExtension("file"w, ".ext"w) == "file.ext");
assert (setExtension("file."d, "ext"d) == "file.ext");
assert (setExtension("file.", ".ext") == "file.ext");
assert (setExtension("file.old"w, "new"w) == "file.new");
assert (setExtension("file.old"d, ".new"d) == "file.new");
auto withExtension(R, C)(R path, C[] ext)
if ((isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) || isNarrowString!R) && !isConvertibleToString!R && isSomeChar!C);
Заменяет существующее расширение файла на новое.
Параметры:
R path Строка или диапазон с произвольным доступом, представляющий файл
C[] ext новое расширение
Возвращает:
Диапазон с путём path, с расширением (если есть) замененым на ext. Тип кодирования элемента возвращаемого диапазона будет таким же, как и у исходного пути.
Смотрите также:
Примеры:
import std.array;
assert (withExtension("file", "ext").array == "file.ext");
assert (withExtension("file"w, ".ext"w).array == "file.ext");
assert (withExtension("file.ext"w, ".").array == "file.");

import std.utf : byChar, byWchar;
assert (withExtension("file".byChar, "ext").array == "file.ext");
assert (withExtension("file"w.byWchar, ".ext"w).array == "file.ext"w);
assert (withExtension("file.ext"w.byWchar, ".").array == "file."w);
immutable(Unqual!C1)[] defaultExtension(C1, C2)(in C1[] path, in C2[] ext)
if (isSomeChar!C1 && is(Unqual!C1 == Unqual!C2));
Параметры:
C1[] path Имя пути.
C2[] ext Расширение по умолчанию.
Возвращает:
Путь, заданный параметром path, с добавленным расширением, заданным параметром ext, если путь ещё его не имеет.
Включение точки в расширение необязательно.
Эта функция всегда распределяет новую строку, за исключением случая, когда path является immutable и уже имеет расширение.
Примеры:
assert (defaultExtension("file", "ext") == "file.ext");
assert (defaultExtension("file", ".ext") == "file.ext");
assert (defaultExtension("file.", "ext")     == "file.");
assert (defaultExtension("file.old", "new") == "file.old");
assert (defaultExtension("file.old", ".new") == "file.old");
auto withDefaultExtension(R, C)(R path, C[] ext)
if ((isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) || isNarrowString!R) && !isConvertibleToString!R && isSomeChar!C);
Задаёт расширение пути path в ext, если оно отсутствует в пути.
Параметры:
R path Файл как строка или диапазон
C[] ext Расширение, может иметь ведущую '.'
Возвращает:
диапазон с результатом
Примеры:
import std.array;
assert (withDefaultExtension("file", "ext").array == "file.ext");
assert (withDefaultExtension("file"w, ".ext").array == "file.ext"w);
assert (withDefaultExtension("file.", "ext").array == "file.");
assert (withDefaultExtension("file", "").array == "file.");

import std.utf : byChar, byWchar;
assert (withDefaultExtension("file".byChar, "ext").array == "file.ext");
assert (withDefaultExtension("file"w.byWchar, ".ext").array == "file.ext"w);
assert (withDefaultExtension("file.".byChar, "ext"d).array == "file.");
assert (withDefaultExtension("file".byChar, "").array == "file.");
immutable(ElementEncodingType!(ElementType!Range))[] buildPath(Range)(Range segments)
if (isInputRange!Range && isSomeString!(ElementType!Range));

pure nothrow @safe immutable(C)[] buildPath(C)(const(C)[][] paths...)
if (isSomeChar!C);
Объединяет один или несколько сегментов пути.
Эта функция принимает набор сегментов пути segments, задаваемых как входной диапазон элементов строки или как набор сроковых аргументов, и объединяет их друг с другом. При необходимости между сегментами вставляются разделители каталога. Если какой-либо из сегментов пути является абсолютным (как это определяет функция isAbsolute), предыдущие сегменты будут отброшены.
В Windows, если один из сегментов пути является корневым, но не является абсолютным (например, \foo), все предыдущие сегменты пути до предыдущего корня будут отброшены. (См. пример ниже.)
Эта функция всегда выделяет память для хранения результирующего пути. Гарантируется, что variadic overload будет выполнять только одно распределение памяти, если paths является лидирующим диапазоном. The variadic overload is guaranteed to only perform a single allocation, as is the range version if paths is a forward range.
Параметры:
Range segments Входной диапазон сегментов для сборки пути.
Возвращает:
Собранный путь.
Примеры:
version (Posix)
{
    assert (buildPath("foo", "bar", "baz") == "foo/bar/baz");
    assert (buildPath("/foo/", "bar/baz")  == "/foo/bar/baz");
    assert (buildPath("/foo", "/bar")      == "/bar");
}

version (Windows)
{
    assert (buildPath("foo", "bar", "baz") == `foo\bar\baz`);
    assert (buildPath(`c:\foo`, `bar\baz`) == `c:\foo\bar\baz`);
    assert (buildPath("foo", `d:\bar`)     == `d:\bar`);
    assert (buildPath("foo", `\bar`)       == `\bar`);
    assert (buildPath(`c:\foo`, `\bar`)    == `c:\bar`);
}
auto chainPath(R1, R2, Ranges...)(R1 r1, R2 r2, Ranges ranges)
if ((isRandomAccessRange!R1 && hasSlicing!R1 && hasLength!R1 && isSomeChar!(ElementType!R1) || isNarrowString!R1 && !isConvertibleToString!R1) && (isRandomAccessRange!R2 && hasSlicing!R2 && hasLength!R2 && isSomeChar!(ElementType!R2) || isNarrowString!R2 && !isConvertibleToString!R2) && (Ranges.length == 0 || is(typeof(chainPath(r2, ranges)))));
Соединяет сегменты пути вместе, чтобы сформировать один путь.
Параметры:
R1 r1 первый сегмент
R2 r2 второй сегмент
Ranges ranges 0 или больше сегментов
Возвращает:
Ленивый диапазон, который является объединением диапазонов r1, r2 и ranges с разделителями пути. Результирующим типом элемента является тип r1.
Смотрите также:
Примеры:
import std.array;
version (Posix)
{
    assert (chainPath("foo", "bar", "baz").array == "foo/bar/baz");
    assert (chainPath("/foo/", "bar/baz").array  == "/foo/bar/baz");
    assert (chainPath("/foo", "/bar").array      == "/bar");
}

version (Windows)
{
    assert (chainPath("foo", "bar", "baz").array == `foo\bar\baz`);
    assert (chainPath(`c:\foo`, `bar\baz`).array == `c:\foo\bar\baz`);
    assert (chainPath("foo", `d:\bar`).array     == `d:\bar`);
    assert (chainPath("foo", `\bar`).array       == `\bar`);
    assert (chainPath(`c:\foo`, `\bar`).array    == `c:\bar`);
}

import std.utf : byChar;
version (Posix)
{
    assert (chainPath("foo", "bar", "baz").array == "foo/bar/baz");
    assert (chainPath("/foo/".byChar, "bar/baz").array  == "/foo/bar/baz");
    assert (chainPath("/foo", "/bar".byChar).array      == "/bar");
}

version (Windows)
{
    assert (chainPath("foo", "bar", "baz").array == `foo\bar\baz`);
    assert (chainPath(`c:\foo`.byChar, `bar\baz`).array == `c:\foo\bar\baz`);
    assert (chainPath("foo", `d:\bar`).array     == `d:\bar`);
    assert (chainPath("foo", `\bar`.byChar).array       == `\bar`);
    assert (chainPath(`c:\foo`, `\bar`w).array    == `c:\bar`);
}
pure nothrow @trusted immutable(C)[] buildNormalizedPath(C)(const(C[])[] paths...)
if (isSomeChar!C);
Выполняет ту же задачу, что и buildPath, разрешая в то же время символы текущего/родительского каталога ("." и ".."), и удаляет лишние разделители каталогов. Возвращает ".", если путь ведет к стартовому каталогу. В Windows прямые косые черты заменяются обратными косыми чертами.
Использование buildNormalizedPath с путями paths, равными null, всегда возвращает null.
Обратите внимание, что эта функция не разрешает символические ссылки.
Эта функция всегда выделяет память для хранения результирующего пути. Используйте asNormalizedPath, чтобы не распределять память.
Параметры:
const(C[])[] paths Массив путей для сборки.
Возвращает:
Собранный путь.
Примеры:
assert (buildNormalizedPath("foo", "..") == ".");

version (Posix)
{
    assert (buildNormalizedPath("/foo/./bar/..//baz/") == "/foo/baz");
    assert (buildNormalizedPath("../foo/.") == "../foo");
    assert (buildNormalizedPath("/foo", "bar/baz/") == "/foo/bar/baz");
    assert (buildNormalizedPath("/foo", "/bar/..", "baz") == "/baz");
    assert (buildNormalizedPath("foo/./bar", "../../", "../baz") == "../baz");
    assert (buildNormalizedPath("/foo/./bar", "../../baz") == "/baz");
}

version (Windows)
{
    assert (buildNormalizedPath(`c:\foo\.\bar/..\\baz\`) == `c:\foo\baz`);
    assert (buildNormalizedPath(`..\foo\.`) == `..\foo`);
    assert (buildNormalizedPath(`c:\foo`, `bar\baz\`) == `c:\foo\bar\baz`);
    assert (buildNormalizedPath(`c:\foo`, `bar/..`) == `c:\foo`);
    assert (buildNormalizedPath(`\\server\share\foo`, `..\bar`) ==
            `\\server\share\bar`);
}
auto asNormalizedPath(R)(R path)
if (isSomeChar!(ElementEncodingType!R) && (isRandomAccessRange!R && hasSlicing!R && hasLength!R || isNarrowString!R) && !isConvertibleToString!R);
Нормализует путь, разрешая символы текущего/родительского каталога ("." и "..""), и удаляет лишние разделители каталогов. Возвращает ".", если путь ведет к стартовому каталогу. В Windows прямые косые черты заменяются обратными косыми чертами.
Использование asNormalizedPath на пустых путях всегда будет возвращать пустой путь.
Не разрешает символические ссылки.
Эта функция всегда выделяет память для хранения результирующего пути. ( На всякий случай, я привёл дословный перевод этого предложения, но, вроде, на самом деле выделения памяти для всей строки с путём не происходит, а в этом предложении ошибка. За это говорит фраза в описании предыдущей функции buildNormalizedPath, а также то, что возвращается не строка, а лидирующий диапазон – прим.пер. ) Используйте buildNormalizedPath для выделения памяти и возврата строки типа string.
Параметры:
R path Строка или диапазон с произвольным доступом, предоставляющий путь для нормализации
Возвращает:
нормализованный путь в виде лидирующего диапазона
Примеры:
import std.array;
assert (asNormalizedPath("foo/..").array == ".");

version (Posix)
{
    assert (asNormalizedPath("/foo/./bar/..//baz/").array == "/foo/baz");
    assert (asNormalizedPath("../foo/.").array == "../foo");
    assert (asNormalizedPath("/foo/bar/baz/").array == "/foo/bar/baz");
    assert (asNormalizedPath("/foo/./bar/../../baz").array == "/baz");
}

version (Windows)
{
    assert (asNormalizedPath(`c:\foo\.\bar/..\\baz\`).array == `c:\foo\baz`);
    assert (asNormalizedPath(`..\foo\.`).array == `..\foo`);
    assert (asNormalizedPath(`c:\foo\bar\baz\`).array == `c:\foo\bar\baz`);
    assert (asNormalizedPath(`c:\foo\bar/..`).array == `c:\foo`);
    assert (asNormalizedPath(`\\server\share\foo\..\bar`).array ==
            `\\server\share\bar`);
}
auto pathSplitter(R)(R path)
if ((isRandomAccessRange!R && hasSlicing!R || isNarrowString!R) && !isConvertibleToString!R);
Разрезает путь path на его элементы.
Параметры:
R path Строка или диапазон с произвольным доступом с поддержкой срезов
Возвращает:
Двунаправленный диапазон частей пути
Примеры:
import std.algorithm.comparison : equal;
import std.conv : to;

assert (equal(pathSplitter("/"), ["/"]));
assert (equal(pathSplitter("/foo/bar"), ["/", "foo", "bar"]));
assert (equal(pathSplitter("foo/../bar//./"), ["foo", "..", "bar", "."]));

version (Posix)
{
    assert (equal(pathSplitter("//foo/bar"), ["/", "foo", "bar"]));
}

version (Windows)
{
    assert (equal(pathSplitter(`foo\..\bar\/.\`), ["foo", "..", "bar", "."]));
    assert (equal(pathSplitter("c:"), ["c:"]));
    assert (equal(pathSplitter(`c:\foo\bar`), [`c:\`, "foo", "bar"]));
    assert (equal(pathSplitter(`c:foo\bar`), ["c:foo", "bar"]));
}
bool isRooted(R)(R path)
if (isRandomAccessRange!R && isSomeChar!(ElementType!R) || is(StringTypeOf!R));
Определяет, начинается ли путь с корневого каталога.
Параметры:
R path Имя с путём
Возвращает:
Начинается ли путь от корневого каталога.
В POSIX эта функция возвращает true тогда и только тогда, когда путь path начинается с косой черты (/).
version (Posix)
{
    assert (isRooted("/"));
    assert (isRooted("/foo"));
    assert (!isRooted("foo"));
    assert (!isRooted("../foo"));
}
В Windows эта функция возвращает значение true, если путь path начинается с корневого каталога текущего диска, с корневого каталога другого диска или с сетевого диска.
version (Windows)
{
    assert (isRooted(`\`));
    assert (isRooted(`\foo`));
    assert (isRooted(`d:\foo`));
    assert (isRooted(`\\foo\bar`));
    assert (!isRooted("foo"));
    assert (!isRooted("d:foo"));
}
pure nothrow @safe bool isAbsolute(R)(R path)
if (isRandomAccessRange!R && isSomeChar!(ElementType!R) || is(StringTypeOf!R));
Определяет, является ли путь path абсолютным или нет.
Параметры:
R path Имя с путём
Возвращает:
Является ли путь path абсолютным или нет.

Пример: В POSIX абсолютный путь начинается с корневого каталога. (Фактически isAbsolute – это просто псевдоним для isRooted.)

version (Posix)
{
    assert (isAbsolute("/"));
    assert (isAbsolute("/foo"));
    assert (!isAbsolute("foo"));
    assert (!isAbsolute("../foo"));
}
В Windows абсолютный путь начинается с корневого каталога конкретного диска. Следовательно, он должен начинаться с d:\ или с d:/, где d обозначает букву диска. Альтернативно, это может быть сетевой путь, то есть путь, начинающийся с двойной (обратной) косой черты.
version (Windows)
{
    assert (isAbsolute(`d:\`));
    assert (isAbsolute(`d:\foo`));
    assert (isAbsolute(`\\foo\bar`));
    assert (!isAbsolute(`\`));
    assert (!isAbsolute(`\foo`));
    assert (!isAbsolute("d:foo"));
}

pure @safe string absolutePath(string path, lazy string base = getcwd());
Преобразует путь path в абсолютный путь.
Используется следующий алгоритм:
  1. Если path пусто, возвращается null.
  2. Если путь path уже является абсолютным, возвращается он.
  3. В противном случае, путь path добавляется к базе base и возвращается результат. Если base не указана, используется текущий рабочий каталог.
Функция выделяет память тогда и только тогда, когда она попадает на третий этап этого алгоритма.
Параметры:
string path Относительный путь для преобразования
string base Каталог, который будет базовым для относительного пути
Возвращает:
строку с преобразованным путём
Исключения:
Exception, если заданный базовый каталог не является абсолютным.
Смотрите также:
asAbsolutePath, которая не рапределяет память
Примеры:
version (Posix)
{
    assert (absolutePath("some/file", "/foo/bar")  == "/foo/bar/some/file");
    assert (absolutePath("../file", "/foo/bar")    == "/foo/bar/../file");
    assert (absolutePath("/some/file", "/foo/bar") == "/some/file");
}

version (Windows)
{
    assert (absolutePath(`some\file`, `c:\foo\bar`)    == `c:\foo\bar\some\file`);
    assert (absolutePath(`..\file`, `c:\foo\bar`)      == `c:\foo\bar\..\file`);
    assert (absolutePath(`c:\some\file`, `c:\foo\bar`) == `c:\some\file`);
    assert (absolutePath(`\`, `c:\`)                   == `c:\`);
    assert (absolutePath(`\some\file`, `c:\foo\bar`)   == `c:\some\file`);
}
auto asAbsolutePath(R)(R path)
if ((isRandomAccessRange!R && isSomeChar!(ElementType!R) || isNarrowString!R) && !isConvertibleToString!R);
Преобразует путь path в абсолютный путь.
Используется следующий алгоритм:
  1. Если path пусто, возвращается null.
  2. Если путь path уже является абсолютным, возвращается он.
  3. В противном случае путь path добавляется к текущему рабочему каталогу, для чего выделяется память.
Параметры:
R path Относительный путь для преобразования
Возвращает:
Преобразованный путь в виде ленивого диапазона
Смотрите также:
absolutePath, которая возвращает выделенную строку
Примеры:
import std.array;
assert(asAbsolutePath(cast(string)null).array == "");
version (Posix)
{
    assert(asAbsolutePath("/foo").array == "/foo");
}
version (Windows)
{
    assert(asAbsolutePath("c:/foo").array == "c:/foo");
}
asAbsolutePath("foo");
string relativePath(CaseSensitive cs = CaseSensitive.osDefault)(string path, lazy string base = getcwd());
Преобразует путь path в относительный путь.
Возвращаемый путь относительно базы base, которая по умолчанию считается текущим рабочим каталогом. Если заданя, база должна быть абсолютным путём, и она всегда считается ссылающейся на каталог. Если путь и база относятся к одному и тому же каталогу, функция возвращает точку ..
Используется следующий алгоритм:
  1. Если путь является относительным каталогом, он возвращается без изменений.
  2. Ищется общий корень между path и base. Если общий корень отсутствует, путь path возвращается без изменений.
  3. Подготавливается строка с большим количеством ../ или ..\, если необходимо, чтобы получить общий корень от базового пути.
  4. Добавляются оставшиеся сегменты пути path к строке и возвращается результат.
На втором этапе компоненты пути сравниваются с использованием filenameCmp!cs, где cs является необязательным параметром шаблона, определяющим, является ли сравнение чувствительным к регистру или нет. Подробнее, смотрите документацию filenameCmp.
Эта функция выделяет память.
Параметры:
cs Будет ли при сопоставлении компонентов имени пути с базовым путём учитываться регистр или нет.
string path Имя с путём
string base Базовый путь для построения относительного пути.
Возвращает:
Относительный путь.
Смотрите также:
asRelativePath, которая не выделяет память.
Исключения:
Exception, если заданный базовый каталог не является абсолютным.
Примеры:
assert (relativePath("foo") == "foo");

version (Posix)
{
    assert (relativePath("foo", "/bar") == "foo");
    assert (relativePath("/foo/bar", "/foo/bar") == ".");
    assert (relativePath("/foo/bar", "/foo/baz") == "../bar");
    assert (relativePath("/foo/bar/baz", "/foo/woo/wee") == "../../bar/baz");
    assert (relativePath("/foo/bar/baz", "/foo/bar") == "baz");
}
version (Windows)
{
    assert (relativePath("foo", `c:\bar`) == "foo");
    assert (relativePath(`c:\foo\bar`, `c:\foo\bar`) == ".");
    assert (relativePath(`c:\foo\bar`, `c:\foo\baz`) == `..\bar`);
    assert (relativePath(`c:\foo\bar\baz`, `c:\foo\woo\wee`) == `..\..\bar\baz`);
    assert (relativePath(`c:\foo\bar\baz`, `c:\foo\bar`) == "baz");
    assert (relativePath(`c:\foo\bar`, `d:\foo`) == `c:\foo\bar`);
}
auto asRelativePath(CaseSensitive cs = CaseSensitive.osDefault, R1, R2)(R1 path, R2 base)
if ((isNarrowString!R1 || isRandomAccessRange!R1 && hasSlicing!R1 && isSomeChar!(ElementType!R1) && !isConvertibleToString!R1) && (isNarrowString!R2 || isRandomAccessRange!R2 && hasSlicing!R2 && isSomeChar!(ElementType!R2) && !isConvertibleToString!R2));
Преобразует путь path в путь относительно базы base.
Возвращаемый путь по отношению к базе, которая обычно является текущим рабочим каталогом. База должна быть абсолютным путем, и она всегда считается ссылкой на каталог. Если путь path и база base относятся к одному и тому же каталогу, функция возвращает '.'.
The following algorithm is used:
  1. Если путь является относительным каталогом, он возвращается без изменений.
  2. Ищется общий корень между path и base. Если общий корень отсутствует, путь path возвращается без изменений.
  3. Подготавливается строка с большим количеством ../ или ..\, если необходимо, чтобы получить общий корень от базового пути.
  4. Добавляются оставшиеся сегменты пути path к строке и возвращается результат.
На втором этапе компоненты пути сравниваются с использованием filenameCmp!cs, где cs является необязательным параметром шаблона, определяющим, является ли сравнение чувствительным к регистру или нет. Подробнее, смотрите документацию filenameCmp.
Параметры:
R1 path путь для преобразования
R2 base абсолютный путь
cs Будет ли при сопоставлении компонентов путей учитываться регистр или нет; по-умолчанию CaseSensitive.osDefault
Возвращает:
Диапазон с произвольным доступом с преобразованным путём
Смотрите также:
Примеры:
import std.array;
version (Posix)
{
    assert (asRelativePath("foo", "/bar").array == "foo");
    assert (asRelativePath("/foo/bar", "/foo/bar").array == ".");
    assert (asRelativePath("/foo/bar", "/foo/baz").array == "../bar");
    assert (asRelativePath("/foo/bar/baz", "/foo/woo/wee").array == "../../bar/baz");
    assert (asRelativePath("/foo/bar/baz", "/foo/bar").array == "baz");
}
else version (Windows)
{
    assert (asRelativePath("foo", `c:\bar`).array == "foo");
    assert (asRelativePath(`c:\foo\bar`, `c:\foo\bar`).array == ".");
    assert (asRelativePath(`c:\foo\bar`, `c:\foo\baz`).array == `..\bar`);
    assert (asRelativePath(`c:\foo\bar\baz`, `c:\foo\woo\wee`).array == `..\..\bar\baz`);
    assert (asRelativePath(`c:/foo/bar/baz`, `c:\foo\woo\wee`).array == `..\..\bar\baz`);
    assert (asRelativePath(`c:\foo\bar\baz`, `c:\foo\bar`).array == "baz");
    assert (asRelativePath(`c:\foo\bar`, `d:\foo`).array == `c:\foo\bar`);
    assert (asRelativePath(`\\foo\bar`, `c:\foo`).array == `\\foo\bar`);
}
else
    static assert(0);
pure nothrow @safe int filenameCharCmp(CaseSensitive cs = CaseSensitive.osDefault)(dchar a, dchar b);
Сравнивает символы имён файлов.
Эта функция может выполняться с учетом регистра или без учета регистра. Контролируется это с помощью параметра шаблона cs, который, если не указан, считается равным CaseSensitive.osDefault.
В Windows символы с обратной и прямой косой чертой (\ и /) считаются равными.
Параметры:
cs Чувствительность к регистру сравнения.
dchar a Символ имени файла.
dchar b Символ имени файла.
Возвращает:
< 0, если a < b, 0, если a == b, и > 0, если a > b.
Примеры:
assert (filenameCharCmp('a', 'a') == 0);
assert (filenameCharCmp('a', 'b') < 0);
assert (filenameCharCmp('b', 'a') > 0);

version (linux)
{
    // Тоже самое, что и вызов filenameCharCmp!(CaseSensitive.yes)(a, b)
    assert (filenameCharCmp('A', 'a') < 0);
    assert (filenameCharCmp('a', 'A') > 0);
}
version (Windows)
{
    // Тоже самое, что и вызов filenameCharCmp!(CaseSensitive.no)(a, b)
    assert (filenameCharCmp('a', 'A') == 0);
    assert (filenameCharCmp('a', 'B') < 0);
    assert (filenameCharCmp('A', 'b') < 0);
}
int filenameCmp(CaseSensitive cs = CaseSensitive.osDefault, Range1, Range2)(Range1 filename1, Range2 filename2)
if (isInputRange!Range1 && isSomeChar!(ElementEncodingType!Range1) && !isConvertibleToString!Range1 && isInputRange!Range2 && isSomeChar!(ElementEncodingType!Range2) && !isConvertibleToString!Range2);
Сравнивает имена файлов
Отдельные символы сравниваются с использованием filenameCharCmp!cs, где cs является необязательным параметром шаблона, определяющим, является ли сравнение чувствительным к регистру или нет.
Обработка недействительных UTF-кодировок определяется реализацией.
Параметры:
cs чувствительность к регистру
Range1 filename1 диапазон для первого имени файла
Range2 filename2 диапазон для имени второго файла
Возвращает:
< 0, если filename1 < filename2, 0, если filename1 == filename2 и > 0, если filename1 > filename2.
Смотрите также:
Примеры:
assert (filenameCmp("abc", "abc") == 0);
assert (filenameCmp("abc", "abd") < 0);
assert (filenameCmp("abc", "abb") > 0);
assert (filenameCmp("abc", "abcd") < 0);
assert (filenameCmp("abcd", "abc") > 0);

version (linux)
{
    // Тоже самое, что и вызов filenameCmp!(CaseSensitive.yes)(filename1, filename2)
    assert (filenameCmp("Abc", "abc") < 0);
    assert (filenameCmp("abc", "Abc") > 0);
}
version (Windows)
{
    // Тоже самое, что и вызов filenameCmp!(CaseSensitive.no)(filename1, filename2)
    assert (filenameCmp("Abc", "abc") == 0);
    assert (filenameCmp("abc", "Abc") == 0);
    assert (filenameCmp("Abc", "abD") < 0);
    assert (filenameCmp("abc", "AbB") > 0);
}
pure nothrow @safe bool globMatch(CaseSensitive cs = CaseSensitive.osDefault, C, Range)(Range path, const(C)[] pattern)
if (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) && !isConvertibleToString!Range && isSomeChar!C && is(Unqual!C == Unqual!(ElementEncodingType!Range)));
Соответствует ли путь path шаблону pattern.
Некоторые символы шаблона имеют особое значение (это метасимволы), и не могут быть экранированы. Вот они:
* Соответствует 0 или более экземплярам любого символа.
? Соответствует в точности одному экземпляру любого символа.
[chars] Соответствует одному экземпляру любого символа, который находится между скобками.
[!chars] Соответствует одному экземпляру любого символа, который не находится между скобками после восклицательного знака.
{string1,string2,} Соответствует любой из указанных строк.
Отдельные символы сравниваются с использованием filenameCharCmp!cs, где cs является необязательным параметром шаблона, определяющим, является ли сравнение чувствительным к регистру или нет. Подробнее, смотрите документацию filenameCharCmp.
Обратите внимание, что разделители каталогов и точки не останавливают метасимвол от соответствия другим частям пути path.
Параметры:
cs Должно ли совпадение быть чувствительным к регистру
Range path Путь, который нужно сопоставить
const(C)[] pattern Шаблон
Возвращает:
true, если pattern соответсвует path, false в противном случае.
Смотрите также:
Примеры:
assert (globMatch("foo.bar", "*"));
assert (globMatch("foo.bar", "*.*"));
assert (globMatch(`foo/foo\bar`, "f*b*r"));
assert (globMatch("foo.bar", "f???bar"));
assert (globMatch("foo.bar", "[fg]???bar"));
assert (globMatch("foo.bar", "[!gh]*bar"));
assert (globMatch("bar.fooz", "bar.{foo,bif}z"));
assert (globMatch("bar.bifz", "bar.{foo,bif}z"));

version (Windows)
{
    // Тоже самое, что и вызов globMatch!(CaseSensitive.no)(path, pattern)
    assert (globMatch("foo", "Foo"));
    assert (globMatch("Goo.bar", "[fg]???bar"));
}
version (linux)
{
    // Тоже самое, что и вызов globMatch!(CaseSensitive.yes)(path, pattern)
    assert (!globMatch("foo", "Foo"));
    assert (!globMatch("Goo.bar", "[fg]???bar"));
}
bool isValidFilename(Range)(Range filename)
if ((isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range && isSomeChar!(ElementEncodingType!Range) || isNarrowString!Range) && !isConvertibleToString!Range);
Проверяет, что данное имя файла или каталога действительны.
Максимальная длина имени файла filename задается константой core.stdc.stdio.FILENAME_MAX. (В Windows это число определяется как максимальное количество кодовых точек UTF-16, и поэтому тест будет давать правильные результаты, только когда filename является строкой wchar.)
В Windows должны быть выполнены следующие критерии (источник):
  • filename не должно содержать символов, целочисленное представление которых находится в диапазоне 0-31.
  • filename не должно содержать ни одного из следующих зарезервированных символов: <>:"/\|?*
  • filename не может заканчиваться пробелом (' ') или точкой ('.').
В POSIX, filename не может содержать прямую косую черту ('/') или нулевой символ ('\0').
Параметры:
Range filename проверяемая строка
Возвращает:
true тогда и только тогда, когда имя файла filename не пустое, не слишком длинное и не содержит недопустимых символов.
Примеры:
import std.utf : byCodeUnit;

assert(isValidFilename("hello.exe".byCodeUnit));
bool isValidPath(Range)(Range path)
if ((isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range && isSomeChar!(ElementEncodingType!Range) || isNarrowString!Range) && !isConvertibleToString!Range);
Проверяет, является ли путь path допустимым.
Как правило, эта функция проверяет, что путь не пуст, и что каждый компонент пути либо удовлетворяет isValidFilename, либо равен "." или "..".
Она не проверяет, указывает ли путь на существующий файл или каталог; Для этого используйте std.file.exists.
В Windows применяются некоторые специальные правила:
  • Если вторым символом пути является двоеточие (':'), первый символ интерпретируется как буква диска и должен находиться в диапазоне A-Z (без учета регистра).
  • Если путь представлен в форме \\server\share\... (UNC-путь), функция isValidFilename применяется к server и share целиком.
  • Если путь начинается с \\?\ (длинный UNC-путь), единственным требованием для остальной части строки является то, что она не содержит нулевой символ.
  • Если путь начинается с \\.\ (пространство имен устройств Win32), эта функция возвращает false; такие пути выходят за рамки применимости этого модуля.
Параметры:
Range path Строка или диапазон символов для проверки
Возвращает:
true, если path является допустимым путём.
Примеры:
assert (isValidPath("/foo/bar"));
assert (!isValidPath("/foo\0/bar"));
assert (isValidPath("/"));
assert (isValidPath("a"));

version (Windows)
{
    assert (isValidPath(`c:\`));
    assert (isValidPath(`c:\foo`));
    assert (isValidPath(`c:\foo\.\bar\\\..\`));
    assert (!isValidPath(`!:\foo`));
    assert (!isValidPath(`c::\foo`));
    assert (!isValidPath(`c:\foo?`));
    assert (!isValidPath(`c:\foo.`));

    assert (isValidPath(`\\server\share`));
    assert (isValidPath(`\\server\share\foo`));
    assert (isValidPath(`\\server\share\\foo`));
    assert (!isValidPath(`\\\server\share\foo`));
    assert (!isValidPath(`\\server\\share\foo`));
    assert (!isValidPath(`\\ser*er\share\foo`));
    assert (!isValidPath(`\\server\sha?e\foo`));
    assert (!isValidPath(`\\server\share\|oo`));

    assert (isValidPath(`\\?\<>:"?*|/\..\.`));
    assert (!isValidPath("\\\\?\\foo\0bar"));

    assert (!isValidPath(`\\.\PhysicalDisk1`));
    assert (!isValidPath(`\\`));
}

import std.utf : byCodeUnit;
assert (isValidPath("/foo/bar".byCodeUnit));
nothrow string expandTilde(string inputPath);
Выполняет тильда-расширение в путях на POSIX-системах. В Windows эта функция ничего не делает.
Существует два способа использования тильда-расширения в пути. Один из них включает использование тильды отдельно или с последующим разделителем пути. В этом случае тильда будет расширяться значением переменной среды HOME. Второй способ – ввести имя пользователя после тильды (т. е. ~john/Mail). Здесь имя пользователя будет искаться в базе данных пользователей (т. е. в /etc/passwd в Unix-системах) и будет расширяться тем путём, который там хранится. Имя пользователя считается строкой после окончания тильды и до первого экземпляра разделителя путей.
Обратите внимание, что использование синтаксиса ~user может давать отличающиеся значения от ~, только если переменная окружения не соответствует значению, хранящемуся в базе данных пользователей.
Когда используется переменная среды, путь не будет изменен, если переменная среды не существует или она пуста. Когда используется версия с базой данных, путь не будет изменен, если пользователь не существует в базе данных, или недостаточно памяти для выполнения запроса.
Эта функция выполняет несколько распределений памяти.
Параметры:
string inputPath Расширяемый путь.
Возвращает:
inputPath с тильда-расширением, или просто inputPath, если он не может быть расширен. Для Windows expandTilde просто возвращает свой аргумент inputPath.

Пример:

void processFile(string path)
{
    // Допустимо вызывать эту функцию с такими путями, как ~/foo
    auto fullPath = expandTilde(path);
    ...
}