Пакет filepath
Обзор
Пакет filepath реализует вспомогательные функции для работы с путями к файлам в соответствии с путями, определёнными целевой операционной системой.
Пакет filepath использует прямые или обратные косые черты в зависимости от операционной системы. Для обработки путей, таких как URL, в которых всегда используются прямые косые черты независимо от операционной системы, см. пакет path.
Указатель
Файлы пакета
match.go path.go path_unix.go symlink.go symlink_unix.go
Константы
const (
Separator = os.PathSeparator
ListSeparator = os.PathListSeparator
) Переменные
ErrBadPattern указывает на некорректный шаблон.
var ErrBadPattern = errors.New("syntax error in pattern") SkipAll используется как возвращаемое значение из WalkFunc, чтобы указать, что все оставшиеся файлы и каталоги следует пропустить. Ни одна функция не возвращает его в качестве ошибки.
var SkipAll error = fs.SkipAll
SkipDir используется как возвращаемое значение из WalkFunc, чтобы указать, что каталог, указанный в вызове, следует пропустить. Ни одна функция не возвращает его в качестве ошибки.
var SkipDir error = fs.SkipDir
func Abs
func Abs(path string) (string, error)
Abs возвращает абсолютное представление пути. Если путь не является абсолютным, он объединяется с текущим рабочим каталогом, чтобы получить абсолютный путь. Имя абсолютного пути для заданного файла не гарантированно уникально. Abs вызывает Clean для результата.
func Base
func Base(path string) string
Base возвращает последний элемент пути. Перед извлечением последнего элемента завершающие разделители пути удаляются. Если путь пуст, Base возвращает ".". Если путь состоит только из разделителей, Base возвращает один разделитель.
Пример
Код:
fmt.Println("On Unix:")
fmt.Println(filepath.Base("/foo/bar/baz.js"))
fmt.Println(filepath.Base("/foo/bar/baz"))
fmt.Println(filepath.Base("/foo/bar/baz/"))
fmt.Println(filepath.Base("dev.txt"))
fmt.Println(filepath.Base("../todo.txt"))
fmt.Println(filepath.Base(".."))
fmt.Println(filepath.Base("."))
fmt.Println(filepath.Base("/"))
fmt.Println(filepath.Base(""))
Вывод:
On Unix: baz.js baz baz dev.txt todo.txt .. . / .
func Clean
func Clean(path string) string
Clean возвращает кратчайшее имя пути, эквивалентное path, полученное исключительно лексической обработкой. Функция итеративно применяет следующие правила, пока дальнейшая обработка не станет невозможной:
- Заменяет несколько элементов Separator одним.
- Удаляет каждый элемент имени пути . (текущий каталог).
- Удаляет каждый внутренний элемент имени пути .. (родительский каталог) вместе с предшествующим ему элементом, отличным от ...
- Удаляет элементы .. в начале корневого пути: то есть заменяет "/.." на "/" в начале пути, если считать, что Separator равен '/'.
Возвращаемый путь заканчивается косой чертой, только если он обозначает корневой каталог, например "/" в Unix или `C:\` в Windows.
Наконец, все косые черты заменяются на Separator.
Если в результате этой обработки получается пустая строка, Clean возвращает строку ".".
В Windows Clean не изменяет имя тома, кроме замены символов "/" на `\`. Например, Clean("//host/share/../x") возвращает `\\host\share\x`.
См. также Rob Pike, «Lexical File Names in Plan 9 or Getting Dot-Dot Right», https://9p.io/sys/doc/lexnames.html
func Dir
func Dir(path string) string
Dir возвращает все элементы пути, кроме последнего, обычно это каталог пути. После удаления последнего элемента Dir вызывает Clean для пути и удаляет завершающие косые черты. Если путь пуст, Dir возвращает ".". Если путь состоит только из разделителей, Dir возвращает один разделитель. Возвращаемый путь не заканчивается разделителем, если только он не является корневым каталогом.
В Windows для имени, содержащего только том, например "C:", Dir возвращает "C:.", то есть текущий каталог на диске C. Чтобы получить корень диска "C:\", используйте VolumeName вместе с разделителем.
Пример
Код:
fmt.Println("On Unix:")
fmt.Println(filepath.Dir("/foo/bar/baz.js"))
fmt.Println(filepath.Dir("/foo/bar/baz"))
fmt.Println(filepath.Dir("/foo/bar/baz/"))
fmt.Println(filepath.Dir("/dirty//path///"))
fmt.Println(filepath.Dir("dev.txt"))
fmt.Println(filepath.Dir("../todo.txt"))
fmt.Println(filepath.Dir(".."))
fmt.Println(filepath.Dir("."))
fmt.Println(filepath.Dir("/"))
fmt.Println(filepath.Dir(""))
Вывод:
On Unix: /foo/bar /foo/bar /foo/bar/baz /dirty/path . .. . . / .
func EvalSymlinks
func EvalSymlinks(path string) (string, error)
EvalSymlinks возвращает имя пути после разрешения всех символических ссылок. Если path является относительным, результат будет относительным к текущему каталогу, если только один из компонентов не является абсолютной символической ссылкой. EvalSymlinks вызывает Clean для результата.
func Ext
func Ext(path string) string
Ext возвращает расширение имени файла, используемое в path. Расширение — это суффикс, начинающийся с последней точки в последнем элементе path; если точки нет, расширение пустое.
Пример
Код:
fmt.Printf("No dots: %q\n", filepath.Ext("index"))
fmt.Printf("One dot: %q\n", filepath.Ext("index.js"))
fmt.Printf("Two dots: %q\n", filepath.Ext("main.test.js"))
Вывод:
No dots: "" One dot: ".js" Two dots: ".js"
func FromSlash
func FromSlash(path string) string
FromSlash возвращает результат замены каждого символа косой черты ('/') в path символом-разделителем. Несколько косых черт заменяются несколькими разделителями.
См. также функцию Localize, которая преобразует путь с разделителями в виде косой черты, используемый пакетом io/fs, в путь операционной системы.
func Glob
func Glob(pattern string) (matches []string, err error)
Glob возвращает имена всех файлов, соответствующих шаблону, или nil, если совпадений нет. Синтаксис шаблонов такой же, как в Match. Шаблон может описывать иерархические имена, например /usr/*/bin/ed (если Separator равен '/').
Glob игнорирует ошибки файловой системы, например ошибки ввода-вывода при чтении каталогов. Единственная возможная возвращаемая ошибка — ErrBadPattern, если шаблон некорректен.
func HasPrefix
func HasPrefix(p, prefix string) bool
HasPrefix существует для обратной совместимости и не должна использоваться.
Устарела: HasPrefix не учитывает границы путей и не игнорирует регистр, когда это необходимо.
func IsAbs
func IsAbs(path string) bool
IsAbs сообщает, является ли путь абсолютным.
Пример
Код:
fmt.Println("On Unix:")
fmt.Println(filepath.IsAbs("/home/gopher"))
fmt.Println(filepath.IsAbs(".bashrc"))
fmt.Println(filepath.IsAbs(".."))
fmt.Println(filepath.IsAbs("."))
fmt.Println(filepath.IsAbs("/"))
fmt.Println(filepath.IsAbs(""))
Вывод:
On Unix: true false false false true false
func IsLocal 1.20
func IsLocal(path string) bool
IsLocal сообщает, обладает ли path при использовании только лексического анализа всеми следующими свойствами:
- находится внутри поддерева, корнем которого является каталог, в котором вычисляется path
- не является абсолютным путем
- не является пустым
- в Windows не является зарезервированным именем, например "NUL"
Если IsLocal(path) возвращает true, то Join(base, path) всегда создаст путь внутри base, а Clean(path) всегда создаст некорневой путь без элементов пути "..".
IsLocal выполняет исключительно лексическую операцию. В частности, она не учитывает влияние символических ссылок, которые могут существовать в файловой системе.
func Join
func Join(elem ...string) string
Join объединяет любое число элементов пути в один путь, разделяя их специфичным для ОС элементом Separator. Пустые элементы игнорируются. Результат очищается. Однако, если список аргументов пуст или все его элементы пусты, Join возвращает пустую строку. В Windows результат будет UNC-путем, только если первый непустой элемент является UNC-путем.
Пример
Код:
fmt.Println("On Unix:")
fmt.Println(filepath.Join("a", "b", "c"))
fmt.Println(filepath.Join("a", "b/c"))
fmt.Println(filepath.Join("a/b", "c"))
fmt.Println(filepath.Join("a/b", "/c"))
fmt.Println(filepath.Join("a/b", "../../../xyz"))
Вывод:
On Unix: a/b/c a/b/c a/b/c a/b/c ../xyz
func Localize 1.23
func Localize(path string) (string, error)
Localize преобразует путь с разделителями в виде косой черты в путь операционной системы. Входной путь должен быть допустимым согласно io/fs.ValidPath.
Localize возвращает ошибку, если путь невозможно представить в операционной системе. Например, путь a\b отклоняется в Windows, где \ является символом-разделителем и не может входить в имя файла.
Путь, возвращаемый Localize, всегда будет локальным согласно IsLocal.
func Match
func Match(pattern, name string) (matched bool, err error)
Match сообщает, соответствует ли name шаблону имени файла оболочки. Синтаксис шаблона:
pattern:
{ term }
term:
'*' matches any sequence of non-Separator characters
'?' matches any single non-Separator character
'[' [ '^' ] { character-range } ']'
character class (must be non-empty)
c matches character c (c != '*', '?', '\\', '[')
'\\' c matches character c (except on Windows)
character-range:
c matches character c (c != '\\', '-', ']')
'\\' c matches character c (except on Windows)
lo '-' hi matches character c for lo <= c <= hi
Сегменты пути в шаблоне должны разделяться символом Separator.
Match требует, чтобы шаблону соответствовало всё name, а не только его подстрока. Единственная возможная возвращаемая ошибка — ErrBadPattern, если шаблон некорректен.
В Windows экранирование отключено. Вместо этого '\\' трактуется как разделитель пути.
Пример
Код:
fmt.Println("On Unix:")
fmt.Println(filepath.Match("/home/catch/*", "/home/catch/foo"))
fmt.Println(filepath.Match("/home/catch/*", "/home/catch/foo/bar"))
fmt.Println(filepath.Match("/home/?opher", "/home/gopher"))
fmt.Println(filepath.Match("/home/\\*", "/home/*"))
Вывод:
On Unix: true <nil> false <nil> true <nil> true <nil>
func Rel
func Rel(basePath, targPath string) (string, error)
Rel возвращает относительный путь, который после объединения с basePath через разделитель лексически эквивалентен targPath. Иными словами, Join(basePath, Rel(basePath, targPath)) эквивалентен самому targPath.
Возвращаемый путь всегда будет относительным к basePath, даже если basePath и targPath не имеют общих элементов. Rel вызывает Clean для результата.
Возвращается ошибка, если targPath невозможно сделать относительным к basePath или для вычисления необходимо знать текущий рабочий каталог.
Пример
Код:
paths := []string{
"/a/b/c",
"/b/c",
"./b/c",
}
base := "/a"
fmt.Println("On Unix:")
for _, p := range paths {
rel, err := filepath.Rel(base, p)
fmt.Printf("%q: %q %v\n", p, rel, err)
}
Вывод:
On Unix: "/a/b/c": "b/c" <nil> "/b/c": "../b/c" <nil> "./b/c": "" Rel: can't make ./b/c relative to /a
func Split
func Split(path string) (dir, file string)
Split разделяет path сразу после последнего Separator, выделяя компонент каталога и компонент имени файла. Если в path нет Separator, Split возвращает пустой dir и устанавливает file равным path. Возвращаемые значения обладают свойством path = dir+file.
Пример
Код:
paths := []string{
"/home/arnie/amelia.jpg",
"/mnt/photos/",
"rabbit.jpg",
"/usr/local//go",
}
fmt.Println("On Unix:")
for _, p := range paths {
dir, file := filepath.Split(p)
fmt.Printf("input: %q\n\tdir: %q\n\tfile: %q\n", p, dir, file)
}
Вывод:
On Unix: input: "/home/arnie/amelia.jpg" dir: "/home/arnie/" file: "amelia.jpg" input: "/mnt/photos/" dir: "/mnt/photos/" file: "" input: "rabbit.jpg" dir: "" file: "rabbit.jpg" input: "/usr/local//go" dir: "/usr/local//" file: "go"
func SplitList
func SplitList(path string) []string
SplitList разделяет список путей, объединённых специфичным для ОС символом ListSeparator, который обычно встречается в переменных окружения PATH или GOPATH. В отличие от strings.Split, SplitList возвращает пустой срез, если передана пустая строка.
Пример
Код:
fmt.Println("On Unix:", filepath.SplitList("/a/b/c:/usr/bin"))
Вывод:
On Unix: [/a/b/c /usr/bin]
func ToSlash
func ToSlash(path string) string
ToSlash возвращает результат замены каждого символа-разделителя в path символом косой черты ('/'). Несколько разделителей заменяются несколькими косыми чертами.
func VolumeName
func VolumeName(path string) string
VolumeName возвращает начальное имя тома. Для "C:\foo\bar" в Windows функция возвращает "C:". Для "\\host\share\foo" функция возвращает "\\host\share". На других платформах функция возвращает "".
func Walk
func Walk(root string, fn WalkFunc) error
Walk обходит дерево файлов, корнем которого является root, вызывая fn для каждого файла или каталога в дереве, включая root.
Все ошибки, возникающие при обходе файлов и каталогов, фильтруются функцией fn: подробности см. в документации WalkFunc.
Файлы обходятся в лексикографическом порядке, что делает результат детерминированным, но требует от Walk чтения всего каталога в память перед началом его обхода.
Walk не следует по символическим ссылкам.
Walk менее эффективна, чем WalkDir, появившаяся в Go 1.16 и избегающая вызова os.Lstat для каждого посещаемого файла или каталога.
Пример
Код:
package filepath_test
import (
"fmt"
"io/fs"
"os"
"path/filepath"
)
func prepareTestDirTree(tree string) (string, error) {
tmpDir, err := os.MkdirTemp("", "")
if err != nil {
return "", fmt.Errorf("error creating temp directory: %v\n", err)
}
err = os.MkdirAll(filepath.Join(tmpDir, tree), 0755)
if err != nil {
os.RemoveAll(tmpDir)
return "", err
}
return tmpDir, nil
}
func ExampleWalk() {
tmpDir, err := prepareTestDirTree("dir/to/walk/skip")
if err != nil {
fmt.Printf("unable to create test dir tree: %v\n", err)
return
}
defer os.RemoveAll(tmpDir)
os.Chdir(tmpDir)
subDirToSkip := "skip"
fmt.Println("On Unix:")
err = filepath.Walk(".", func(path string, info fs.FileInfo, err error) error {
if err != nil {
fmt.Printf("prevent panic by handling failure accessing a path %q: %v\n", path, err)
return err
}
if info.IsDir() && info.Name() == subDirToSkip {
fmt.Printf("skipping a dir without errors: %+v \n", info.Name())
return filepath.SkipDir
}
fmt.Printf("visited file or dir: %q\n", path)
return nil
})
if err != nil {
fmt.Printf("error walking the path %q: %v\n", tmpDir, err)
return
}
// Output:
// On Unix:
// visited file or dir: "."
// visited file or dir: "dir"
// visited file or dir: "dir/to"
// visited file or dir: "dir/to/walk"
// skipping a dir without errors: skip
}
func WalkDir 1.16
func WalkDir(root string, fn fs.WalkDirFunc) error
WalkDir обходит дерево файлов, корнем которого является root, вызывая fn для каждого файла или каталога в дереве, включая root.
Все ошибки, возникающие при обходе файлов и каталогов, фильтруются функцией fn: подробности см. в документации fs.WalkDirFunc.
Файлы обходятся в лексикографическом порядке, что делает результат детерминированным, но требует от WalkDir чтения всего каталога в память перед началом его обхода.
WalkDir не следует по символическим ссылкам.
WalkDir вызывает fn, передавая пути, в которых используется символ-разделитель, соответствующий операционной системе. Это отличается от io/fs.WalkDir, которая всегда использует пути с разделителями в виде косой черты.
type WalkFunc
WalkFunc — это тип функции, вызываемой Walk для посещения каждого файла или каталога.
Аргумент path содержит аргумент, переданный Walk, в качестве префикса. То есть, если Walk вызвана с аргументом root "dir" и находит в этом каталоге файл с именем "a", функция обхода будет вызвана с аргументом "dir/a".
Каталог и файл объединяются с помощью Join, которая может очистить имя каталога: если Walk вызвана с аргументом root "x/../dir" и находит в этом каталоге файл с именем "a", функция обхода будет вызвана с аргументом "dir/a", а не "x/../dir/a".
Аргумент info содержит fs.FileInfo для указанного пути.
Результат-ошибка, возвращаемый функцией, определяет, как Walk продолжит работу. Если функция возвращает специальное значение SkipDir, Walk пропускает текущий каталог (path, если info.IsDir() имеет значение true, иначе родительский каталог path). Если функция возвращает специальное значение SkipAll, Walk пропускает все оставшиеся файлы и каталоги. В противном случае, если функция возвращает ненулевую ошибку, Walk полностью останавливается и возвращает эту ошибку.
Аргумент err сообщает об ошибке, связанной с path, указывая, что Walk не будет обходить этот каталог. Функция может решить, как обработать эту ошибку; как описано выше, возврат ошибки приведёт к остановке обхода всего дерева функцией Walk.
Walk вызывает функцию с ненулевым аргументом err в двух случаях.
Во-первых, если вызов os.Lstat для корневого каталога или любого каталога или файла в дереве завершается ошибкой, Walk вызывает функцию, устанавливая path равным пути этого каталога или файла, info равным nil, а err — ошибке, возвращённой os.Lstat.
Во-вторых, если метод Readdirnames каталога завершается ошибкой, Walk вызывает функцию, устанавливая path равным пути каталога, info — равным fs.FileInfo, описывающему каталог, а err — ошибке, возвращённой Readdirnames.
type WalkFunc func(path string, info fs.FileInfo, err error) error
© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/path/filepath/