Все функции, за исключением
expandTilde (и, в некоторых случаях,
absolutePath и
relativePath), являются чистыми функциями, предназначенными для манипуляции над строками; они не зависят от какого-либо состояния вне программы и не выполняют никаких реальных действий над файловой системой. Это приводит к тому, что модуль не делает различий между путём, указывающим на каталог, и путём, указывающим на файл, и не знает, действительно ли объект, на который указывает путь, существует в файловой системе. Чтобы различать эти случаи, используйте
std.file.isDir и
std.file.exists.
Обратите внимание, что в Windows как обратная косая черта (
\), так и прямая косая черта (
/) в принципе являются допустимыми разделителями каталогов. Этот модуль считает их равноправными, но в случае добавления нового разделителя будет использоваться обратная косая черта. Кроме того, функция
buildNormalizedPath заменит на этой платформе все прямые слэши на обратную косую черту.
В общем случае, функции этого модуля предполагают, что входные пути правильно сформированы. (То есть они не должны содержать недопустимые символы, они должны следовать формату путей файловой системы и т. д.). Результат вызова функции на неверно сформированном пути не определён. Если существует вероятность того, что путь или имя файла окажутся ошибочными (например, когда их вводит пользователь), иногда бывает желательно использовать функции
isValidFilename и
isValidPath для их проверки.
Большинство функций не выполняют никаких распределений памяти, и если возвращается строка, она обычно является срезом входной строки. Если всё-же функция выделяет память, это явно упоминается в документации.
enum string
dirSeparator
;
Строка, используемая для разделения имен каталогов в пути. Под POSIX это прямая косая черта, под Windows – обратная косая черта.
enum string
pathSeparator
;
Строка разделителя путей. Двоеточие под POSIX, точка с запятой под Windows.
pure nothrow @nogc @safe bool
isDirSeparator
(dchar
c
);
Определяет, является ли данный символ разделителем каталогов.
В Windows сюда включается как \, так и /. На POSIX это только /.
enum
CaseSensitive
: bool;
Это перечисление используется как аргумент шаблона для функций, которые сравнивают имена файлов, и служит для определения, является ли сравнение чувствительным к регистру или нет.
Имена файлов не чувствительны к регистру
Имена файлов чувствительны к регистру
Значение по умолчанию (или общепринятое) для текущей платформы. То есть, 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");
auto
dirName
(R)(R
path
)
if
((isRandomAccessRange!R && hasSlicing!R && hasLength!R
&& isSomeChar!(ElementType!R) || isNarrowString!R) &&
!isConvertibleToString!R);
Возвращает часть пути с каталогом. В 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
, если в пути отсутствует корень.
Возвращает: Кусочек пути.
Примеры: 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 путь возвращается без изменений.
Возвращает: Кусочек пути без компонента, представляющего диск.
Примеры: 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));
-
Возвращает:
Расширение из имени файла, включает точку.
Если расширение отсутствует, возвращается
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));
Определяет, начинается ли путь с корневого каталога.
Возвращает:
Начинается ли путь от корневого каталога.
В 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
абсолютным или нет.
Возвращает: Является ли путь 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
в абсолютный путь.
Используется следующий алгоритм:
- Если
path
пусто, возвращается null
.
-
Если путь
path
уже является абсолютным, возвращается он.
-
В противном случае, путь
path
добавляется к базе base
и возвращается результат. Если base
не указана, используется текущий рабочий каталог.
Функция выделяет память тогда и только тогда, когда она попадает на третий этап этого алгоритма.
Параметры: string path |
Относительный путь для преобразования |
string base |
Каталог, который будет базовым для относительного пути |
Возвращает: строку с преобразованным путём
Исключения: Exception, если заданный базовый каталог не является абсолютным.
Примеры: 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
в абсолютный путь.
Используется следующий алгоритм:
- Если
path
пусто, возвращается null
.
- Если путь
path
уже является абсолютным, возвращается он.
-
В противном случае путь
path
добавляется к текущему рабочему каталогу, для чего выделяется память.
Параметры: R path |
Относительный путь для преобразования |
Возвращает: Преобразованный путь в виде ленивого диапазона
Примеры: 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
, которая по умолчанию считается текущим рабочим каталогом. Если заданя, база должна быть абсолютным путём, и она всегда считается ссылающейся на каталог. Если путь и база относятся к одному и тому же каталогу, функция возвращает точку
..
Используется следующий алгоритм:
-
Если путь является относительным каталогом, он возвращается без изменений.
-
Ищется общий корень между
path
и base
. Если общий корень отсутствует, путь path
возвращается без изменений.
-
Подготавливается строка с большим количеством ../ или ..\, если необходимо, чтобы получить общий корень от базового пути.
-
Добавляются оставшиеся сегменты пути
path
к строке и возвращается результат.
На втором этапе компоненты пути сравниваются с использованием
filenameCmp!cs, где
cs является необязательным параметром шаблона, определяющим, является ли сравнение чувствительным к регистру или нет. Подробнее, смотрите документацию
filenameCmp.
Эта функция выделяет память.
Параметры: cs |
Будет ли при сопоставлении компонентов имени пути с базовым путём учитываться регистр или нет.
|
string path |
Имя с путём |
string base |
Базовый путь для построения относительного пути. |
Возвращает: Относительный путь.
Исключения: 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:
-
Если путь является относительным каталогом, он возвращается без изменений.
- Ищется общий корень между
path
и base
. Если общий корень отсутствует, путь path
возвращается без изменений.
- Подготавливается строка с большим количеством ../ или ..\, если необходимо, чтобы получить общий корень от базового пути.
- Добавляются оставшиеся сегменты пути
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)
{
assert (filenameCharCmp('A', 'a') < 0);
assert (filenameCharCmp('a', 'A') > 0);
}
version (Windows)
{
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)
{
assert (filenameCmp("Abc", "abc") < 0);
assert (filenameCmp("abc", "Abc") > 0);
}
version (Windows)
{
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)
{
assert (globMatch("foo", "Foo"));
assert (globMatch("Goo.bar", "[fg]???bar"));
}
version (linux)
{
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)
{
auto fullPath = expandTilde(path);
...
}