System.FilePath.Windows
| Авторские права | (c) Нейл Митчелл 2005-2014 |
|---|---|
| Лицензия | BSD3 |
| Поддержка | ndmitchell@gmail.com |
| Стабильность | стабильная |
| Переносимость | переносимая |
| Безопасный Haskell | Безопасный |
| Язык | Haskell98 |
Содержание
Описание
Библиотека для манипуляций с FilePath путями в стиле Windows на всех платформах. Импорт System.FilePath обычно предпочтительнее.
Рассмотрим пример FilePath: /directory/file.ext
Мы можем использовать следующие функции для извлечения частей.
-
takeFileNameдаёт"file.ext" -
takeDirectoryдаёт"/directory" -
takeExtensionдаёт".ext" -
dropExtensionдаёт"/directory/file" -
takeBaseNameдаёт"file"
И мы могли бы построить эквивалентный путь с помощью следующих выражений:
Каждая функция в этом модуле документирована с несколькими примерами, которые также используются в качестве тестов.
Вот несколько примеров использования функций filepath вместе:
Пример 1: Найти возможные расположения модуля Haskell Test импортированного из модуля Main:
[replaceFileNamepath_to_main "Test"<.>ext | ext <- ["hs","lhs"] ]
Пример 2: Скачать файл из url и сохранить его на диск:
do let file =makeValidurl System.IO.createDirectoryIfMissing True (takeDirectoryfile)
Пример 3: Скомпилировать файл Haskell, поместив файл .hi в interface:
takeDirectoryfile</>"interface"</>(takeFileNamefile-<.>"hi")
Ссылки: [1] Именование файлов, путей и имен пространств имён (Microsoft MSDN)
Предикаты разделителей
type FilePath = String Источник
Имена файлов и каталогов — это значения типа String, чёткое значение которых зависит от операционной системы. Файлы могут быть открыты, что даёт дескриптор, который затем может быть использован для работы с содержимым этого файла.
pathSeparator :: Char Источник
Символ, разделяющий каталоги. В случае, когда возможно несколько символов, pathSeparator является 'идеальным'.
Windows: pathSeparator == '\\' Posix: pathSeparator == '/' isPathSeparator pathSeparator
pathSeparators :: [Char] Источник
Список всех возможных разделителей.
Windows: pathSeparators == ['\\', '/'] Posix: pathSeparators == ['/'] pathSeparator `elem` pathSeparators
isPathSeparator :: Char -> Bool Источник
Вместо использования (== pathSeparator), используйте это. Проверка, является ли символ разделителем пути.
isPathSeparator a == (a `elem` pathSeparators)
searchPathSeparator :: Char Источник
Символ, используемый для разделения записей в переменной среды $PATH.
Windows: searchPathSeparator == ';' Posix: searchPathSeparator == ':'
isSearchPathSeparator :: Char -> Bool Источник
Является ли символ разделителем файла?
isSearchPathSeparator a == (a == searchPathSeparator)
Символ расширения файла.
extSeparator == '.'
isExtSeparator :: Char -> Bool Источник
Является ли символ символом расширения?
isExtSeparator a == (a == extSeparator)
$PATH методы
splitSearchPath :: String -> [FilePath] Источник
Разделить строку по символу searchPathSeparator.
Следуя рекомендациям в http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html
Posix: splitSearchPath "File1:File2:File3" == ["File1","File2","File3"] Posix: splitSearchPath "File1::File2:File3" == ["File1",".","File2","File3"] Windows: splitSearchPath "File1;File2;File3" == ["File1","File2","File3"] Windows: splitSearchPath "File1;;File2;File3" == ["File1","File2","File3"] Windows: splitSearchPath "File1;\"File2\";File3" == ["File1","File2","File3"]
getSearchPath :: IO [FilePath] Источник
Получить список FilePath в переменной $PATH.
Функции расширения
splitExtension :: FilePath -> (String, String) Источник
Разделить по расширению. addExtension — обратное действие.
splitExtension "/directory/path.ext" == ("/directory/path",".ext")
uncurry (++) (splitExtension x) == x
Valid x => uncurry addExtension (splitExtension x) == x
splitExtension "file.txt" == ("file",".txt")
splitExtension "file" == ("file","")
splitExtension "file/file.txt" == ("file/file",".txt")
splitExtension "file.txt/boris" == ("file.txt/boris","")
splitExtension "file.txt/boris.ext" == ("file.txt/boris",".ext")
splitExtension "file/path.txt.bob.fred" == ("file/path.txt.bob",".fred")
splitExtension "file/path.txt/" == ("file/path.txt/","")
takeExtension :: FilePath -> String Источник
Получить расширение файла, возвращает "" для отсутствия расширения, .ext в противном случае.
takeExtension "/directory/path.ext" == ".ext" takeExtension x == snd (splitExtension x) Valid x => takeExtension (addExtension x "ext") == ".ext" Valid x => takeExtension (replaceExtension x "ext") == ".ext"
replaceExtension :: FilePath -> String -> FilePath Источник
Установить расширение файла, перезаписывая существующее, эквивалентно <.>.
replaceExtension "/directory/path.txt" "ext" == "/directory/path.ext" replaceExtension "/directory/path.txt" ".ext" == "/directory/path.ext" replaceExtension "file.txt" ".bob" == "file.bob" replaceExtension "file.txt" "bob" == "file.bob" replaceExtension "file" ".bob" == "file.bob" replaceExtension "file.txt" "" == "file" replaceExtension "file.fred.bob" "txt" == "file.fred.txt" replaceExtension x y == addExtension (dropExtension x) y
(-<.>) :: FilePath -> String -> FilePath infixr 7 Источник
Удалить текущее расширение и добавить другое, эквивалентно replaceExtension.
"/directory/path.txt" -<.> "ext" == "/directory/path.ext" "/directory/path.txt" -<.> ".ext" == "/directory/path.ext" "foo.o" -<.> "c" == "foo.c"
dropExtension :: FilePath -> FilePath Источник
Удалить последнее расширение и точку перед ним.
dropExtension "/directory/path.ext" == "/directory/path" dropExtension x == fst (splitExtension x)
addExtension :: FilePath -> String -> FilePath Источник
Добавить расширение, даже если оно уже есть, эквивалентно <.>.
addExtension "/directory/path" "ext" == "/directory/path.ext" addExtension "file.txt" "bib" == "file.txt.bib" addExtension "file." ".bib" == "file..bib" addExtension "file" ".bib" == "file.bib" addExtension "/" "x" == "/.x" Valid x => takeFileName (addExtension (addTrailingPathSeparator x) "ext") == ".ext" Windows: addExtension "\\\\share" ".txt" == "\\\\share\\.txt"
hasExtension :: FilePath -> Bool Источник
Указанный файл имеет расширение?
hasExtension "/directory/path.ext" == True hasExtension "/directory/path" == False null (takeExtension x) == not (hasExtension x)
(<.>) :: FilePath -> String -> FilePath infixr 7 Источник
Добавить расширение, даже если оно уже есть, эквивалентно addExtension.
"/directory/path" <.> "ext" == "/directory/path.ext" "/directory/path" <.> ".ext" == "/directory/path.ext"
splitExtensions :: FilePath -> (FilePath, String) Источник
Разделить по всем расширениям.
splitExtensions "/directory/path.ext" == ("/directory/path",".ext")
splitExtensions "file.tar.gz" == ("file",".tar.gz")
uncurry (++) (splitExtensions x) == x
Valid x => uncurry addExtension (splitExtensions x) == x
splitExtensions "file.tar.gz" == ("file",".tar.gz")
dropExtensions :: ПутьКФайлу -> ПутьКФайлу Исходныйкод
Удалить все расширения.
dropExtensions "/directory/path.ext" == "/directory/path" dropExtensions "file.tar.gz" == "file" not $ hasExtension $ dropExtensions x not $ any isExtSeparator $ takeFileName $ dropExtensions x
takeExtensions :: ПутьКФайлу -> Строка Исходныйкод
Получить все расширения.
takeExtensions "/directory/path.ext" == ".ext" takeExtensions "file.tar.gz" == ".tar.gz"
Функции для имен файлов/каталогов
splitFileName :: ПутьКФайлу -> (Строка, Строка) Исходныйкод
Разделить имя файла на каталог и имя файла. combine - обратная функция. Первая часть часто заканчивается слешем.
splitFileName "/directory/file.ext" == ("/directory/","file.ext")
Valid x => uncurry (</>) (splitFileName x) == x || fst (splitFileName x) == "./"
Valid x => isValid (fst (splitFileName x))
splitFileName "file/bob.txt" == ("file/", "bob.txt")
splitFileName "file/" == ("file/", "")
splitFileName "bob" == ("./", "bob")
Posix: splitFileName "/" == ("/","")
Windows: splitFileName "c:" == ("c:","")
takeFileName :: ПутьКФайлу -> ПутьКФайлу Исходныйкод
Получить имя файла.
takeFileName "/directory/file.ext" == "file.ext" takeFileName "test/" == "" takeFileName x `isSuffixOf` x takeFileName x == snd (splitFileName x) Valid x => takeFileName (replaceFileName x "fred") == "fred" Valid x => takeFileName (x </> "fred") == "fred" Valid x => isRelative (takeFileName x)
replaceFileName :: ПутьКФайлу -> Строка -> ПутьКФайлу Исходныйкод
Установить имя файла.
replaceFileName "/directory/other.txt" "file.ext" == "/directory/file.ext" Valid x => replaceFileName x (takeFileName x) == x
dropFileName :: ПутьКФайлу -> ПутьКФайлу Исходныйкод
Удалить имя файла. В отличие от takeDirectory, эта функция оставит символ разделителя каталогов в конце пути к каталогу.
dropFileName "/directory/file.ext" == "/directory/" dropFileName x == fst (splitFileName x)
takeBaseName :: ПутьКФайлу -> Строка Исходныйкод
Получить базовое имя без расширения или пути.
takeBaseName "/directory/file.ext" == "file" takeBaseName "file/test.txt" == "test" takeBaseName "dave.ext" == "dave" takeBaseName "" == "" takeBaseName "test" == "test" takeBaseName (addTrailingPathSeparator x) == "" takeBaseName "file/file.tar.gz" == "file.tar"
replaceBaseName :: ПутьКФайлу -> Строка -> ПутьКФайлу Исходныйкод
Установить базовое имя.
replaceBaseName "/directory/other.ext" "file" == "/directory/file.ext" replaceBaseName "file/test.txt" "bob" == "file/bob.txt" replaceBaseName "fred" "bill" == "bill" replaceBaseName "/dave/fred/bob.gz.tar" "new" == "/dave/fred/new.tar" Valid x => replaceBaseName x (takeBaseName x) == x
takeDirectory :: ПутьКФайлу -> ПутьКФайлу Исходныйкод
Получить имя каталога, перейдя на один уровень выше.
takeDirectory "/directory/other.ext" == "/directory"
takeDirectory x `isPrefixOf` x || takeDirectory x == "."
takeDirectory "foo" == "."
takeDirectory "/" == "/"
takeDirectory "/foo" == "/"
takeDirectory "/foo/bar/baz" == "/foo/bar"
takeDirectory "/foo/bar/baz/" == "/foo/bar/baz"
takeDirectory "foo/bar/baz" == "foo/bar"
Windows: takeDirectory "foo\\bar" == "foo"
Windows: takeDirectory "foo\\bar\\\\" == "foo\\bar"
Windows: takeDirectory "C:\\" == "C:\\"
replaceDirectory :: ПутьКФайлу -> Строка -> ПутьКФайлу Исходныйкод
Установить каталог, сохраняя имя файла.
replaceDirectory "root/file.ext" "/directory/" == "/directory/file.ext" Valid x => replaceDirectory x (takeDirectory x) `equalFilePath` x
combine :: ПутьКФайлу -> ПутьКФайлу -> ПутьКФайлу Исходныйкод
Объединить два пути. Если второй путь начинается с символа разделителя пути или буквенного обозначения диска, возвращает второй путь.
Valid x => combine (takeDirectory x) (takeFileName x) `equalFilePath` x
Объединённые: > Posix: combine "" "test" == "test" > Posix: combine "home" "bob" == "home/bob" > Posix: combine "x:" "foo" == "x:/foo" > Windows: combine C:\\foo "bar" == C:\\foo\\bar > Windows: combine "home" "bob" == "home\bob"
Не объединённые: > Posix: combine "home" "bob" == "bob" > Windows: combine "home" C:\\bob == C:\\bob
Не объединённые (сложный случай): В Windows, если путь к файлу начинается с одиночного слеша, он является относительным к корню текущего диска. В [1] это (путано) называется абсолютным путём. Текущее поведение combine — никогда не объединять такие пути.
Windows: combine "home" "/bob" == "/bob" Windows: combine "home" "\\bob" == "\\bob" Windows: combine "C:\\home" "\\bob" == "\\bob"
В Windows, из [1]: «Если имя файла начинается только с обозначения диска, но не с обратного слеша после двоеточия, оно интерпретируется как относительный путь к текущему каталогу на диске с указанной буквой». Текущее поведение combine — никогда не объединять такие пути.
Windows: combine "D:\\foo" "C:bar" == "C:bar" Windows: combine "C:\\foo" "C:bar" == "C:bar"
(</>) :: ПутьКФайлу -> ПутьКФайлу -> ПутьКФайлу infixr 5 Исходныйкод
Соединить два значения с разделителем пути. Примеры и замечания см. в эквивалентной функции combine.
Posix: "/directory" </> "file.ext" == "/directory/file.ext" Windows: "/directory" </> "file.ext" == "/directory\\file.ext"
splitPath :: ПутьКФайлу -> [ПутьКФайлу] Исходныйкод
Разбить путь по разделителю каталогов.
splitPath "/directory/file.ext" == ["/","directory/","file.ext"] concat (splitPath x) == x splitPath "test//item/" == ["test//","item/"] splitPath "test/item/file" == ["test/","item/","file"] splitPath "" == [] Windows: splitPath "c:\\test\\path" == ["c:\\","test\\","path"] Posix: splitPath "/file/test" == ["/","file/","test"]
joinPath :: [ПутьКФайлу] -> ПутьКФайлу Исходныйкод
Объединить элементы пути обратно.
joinPath ["/","directory/","file.ext"] == "/directory/file.ext" Valid x => joinPath (splitPath x) == x joinPath [] == "" Posix: joinPath ["test","file","path"] == "test/file/path"
splitDirectories :: ПутьКФайлу -> [ПутьКФайлу] Исходныйкод
То же, что и splitPath, но не добавляет слеши в конец каждого элемента.
splitDirectories "/directory/file.ext" == ["/","directory","file.ext"]
splitDirectories "test/file" == ["test","file"]
splitDirectories "/test/file" == ["/","test","file"]
Windows: splitDirectories "C:\\test\\file" == ["C:\\", "test", "file"]
Valid x => joinPath (splitDirectories x) `equalFilePath` x
splitDirectories "" == []
Windows: splitDirectories "C:\\test\\\\\\file" == ["C:\\", "test", "file"]
splitDirectories "/test///file" == ["/","test","file"]
Функции для дисков
splitDrive :: ПутьКФайлу -> (ПутьКФайлу, ПутьКФайлу) Исходныйкод
Разделить путь на диск и остальную часть пути. В Posix, / — это диск.
uncurry (++) (splitDrive x) == x
Windows: splitDrive "file" == ("","file")
Windows: splitDrive "c:/file" == ("c:/","file")
Windows: splitDrive "c:\\file" == ("c:\\","file")
Windows: splitDrive "\\\\shared\\test" == ("\\\\shared\\","test")
Windows: splitDrive "\\\\shared" == ("\\\\shared","")
Windows: splitDrive "\\\\?\\UNC\\shared\\file" == ("\\\\?\\UNC\\shared\\","file")
Windows: splitDrive "\\\\?\\UNCshared\\file" == ("\\\\?\\","UNCshared\\file")
Windows: splitDrive "\\\\?\\d:\\file" == ("\\\\?\\d:\\","file")
Windows: splitDrive "/d" == ("","/d")
Posix: splitDrive "/test" == ("/","test")
Posix: splitDrive "//test" == ("//","test")
Posix: splitDrive "test/file" == ("","test/file")
Posix: splitDrive "file" == ("","file")
joinDrive :: ПутьКФайлу -> ПутьКФайлу -> ПутьКФайлу Исходныйкод
Объединить диск и остальную часть пути.
Valid x => uncurry joinDrive (splitDrive x) == x Windows: joinDrive "C:" "foo" == "C:foo" Windows: joinDrive "C:\\" "bar" == "C:\\bar" Windows: joinDrive "\\\\share" "foo" == "\\\\share\\foo" Windows: joinDrive "/:" "foo" == "/:\\foo"
takeDrive :: ПутьКФайлу -> ПутьКФайлу Исходныйкод
Получить диск из пути к файлу.
takeDrive x == fst (splitDrive x)
hasDrive :: ПутьКФайлу -> Булево Исходныйкод
Содержит ли путь диск.
not (hasDrive x) == null (takeDrive x)
Posix: hasDrive "/foo" == True
Windows: hasDrive "C:\\foo" == True
Windows: hasDrive "C:foo" == True
hasDrive "foo" == False
hasDrive "" == False
dropDrive :: ПутьКФайлу -> ПутьКФайлу Исходныйкод
Удалить диск, если он существует.
dropDrive x == snd (splitDrive x)
isDrive :: ПутьКФайлу -> Булево Исходныйкод
Является ли элемент диском
Posix: isDrive "/" == True
Posix: isDrive "/foo" == False
Windows: isDrive "C:\\" == True
Windows: isDrive "C:\\foo" == False
isDrive "" == False
Функции для слешей в конце пути
hasTrailingPathSeparator :: ПутьКФайлу -> Булево Исходныйкод
Является ли элемент каталогом или заканчивается ли последний символ разделителем каталогов?
hasTrailingPathSeparator "test" == False hasTrailingPathSeparator "test/" == True
addTrailingPathSeparator :: ПутьКФайлу -> ПутьКФайлу Исходныйкод
Добавить символ разделителя каталогов в конце, если его там нет.
hasTrailingPathSeparator (addTrailingPathSeparator x) hasTrailingPathSeparator x ==> addTrailingPathSeparator x == x Posix: addTrailingPathSeparator "test/rest" == "test/rest/"
dropTrailingPathSeparator :: ПутьКФайлу -> ПутьКФайлу Исходный код
Удаляет все конечные разделители пути
dropTrailingPathSeparator "file/test/" == "file/test"
dropTrailingPathSeparator "/" == "/"
Windows: dropTrailingPathSeparator "\\" == "\\"
Posix: not (hasTrailingPathSeparator (dropTrailingPathSeparator x)) || isDrive x
Манипуляции с именами файлов
normalise :: ПутьКФайлу -> ПутьКФайлу Исходный код
Нормализует имя файла
- // вне диска может быть пустым
- / ->
pathSeparator - ./ -> ""
Posix: normalise "/file/\\test////" == "/file/\\test/"
Posix: normalise "/file/./test" == "/file/test"
Posix: normalise "/test/file/../bob/fred/" == "/test/file/../bob/fred/"
Posix: normalise "../bob/fred/" == "../bob/fred/"
Posix: normalise "./bob/fred/" == "bob/fred/"
Windows: normalise "c:\\file/bob\\" == "C:\\file\\bob\\"
Windows: normalise "c:\\" == "C:\\"
Windows: normalise "C:.\\" == "C:"
Windows: normalise "\\\\server\\test" == "\\\\server\\test"
Windows: normalise "//server/test" == "\\\\server\\test"
Windows: normalise "c:/file" == "C:\\file"
Windows: normalise "/file" == "\\file"
Windows: normalise "\\" == "\\"
Windows: normalise "/./" == "\\"
normalise "." == "."
Posix: normalise "./" == "./"
Posix: normalise "./." == "./"
Posix: normalise "/./" == "/"
Posix: normalise "/" == "/"
Posix: normalise "bob/fred/." == "bob/fred/"
Posix: normalise "//home" == "/home"
equalFilePath :: ПутьКФайлу -> ПутьКФайлу -> Булево Исходный код
Равенство двух путей. Если вы сначала вызовете System.Directory.canonicalizePath, у вас будет гораздо больше шансов на успех. Обратите внимание, что эта функция не следует за символическими ссылками или DOSNAM~1.
x == y ==> equalFilePath x y
normalise x == normalise y ==> equalFilePath x y
equalFilePath "foo" "foo/"
not (equalFilePath "foo" "/foo")
Posix: not (equalFilePath "foo" "FOO")
Windows: equalFilePath "foo" "FOO"
Windows: not (equalFilePath "C:" "C:/")
makeRelative :: ПутьКФайлу -> ПутьКФайлу -> ПутьКФайлу Исходный код
Сжимает имя файла, основываясь на относительном пути.
Соответствующая makeAbsolute функция может быть найдена в System.Directory.
makeRelative "/directory" "/directory/file.ext" == "file.ext"
Valid x => makeRelative (takeDirectory x) x `equalFilePath` takeFileName x
makeRelative x x == "."
Valid x y => equalFilePath x y || (isRelative x && makeRelative y x == x) || equalFilePath (y </> makeRelative y x) x
Windows: makeRelative "C:\\Home" "c:\\home\\bob" == "bob"
Windows: makeRelative "C:\\Home" "c:/home/bob" == "bob"
Windows: makeRelative "C:\\Home" "D:\\Home\\Bob" == "D:\\Home\\Bob"
Windows: makeRelative "C:\\Home" "C:Home\\Bob" == "C:Home\\Bob"
Windows: makeRelative "/Home" "/home/bob" == "bob"
Windows: makeRelative "/" "//" == "//"
Posix: makeRelative "/Home" "/home/bob" == "/home/bob"
Posix: makeRelative "/home/" "/home/bob/foo/bar" == "bob/foo/bar"
Posix: makeRelative "/fred" "bob" == "bob"
Posix: makeRelative "/file/test" "/file/test/fred" == "fred"
Posix: makeRelative "/file/test" "/file/test/fred/" == "fred/"
Posix: makeRelative "some/path" "some/path/a/b/c" == "a/b/c"
isRelative :: ПутьКФайлу -> Булево Исходный код
Является ли путь относительным или он закреплен за корнем?
Windows: isRelative "path\\test" == True Windows: isRelative "c:\\test" == False Windows: isRelative "c:test" == True Windows: isRelative "c:\\" == False Windows: isRelative "c:/" == False Windows: isRelative "c:" == True Windows: isRelative "\\\\foo" == False Windows: isRelative "\\\\?\\foo" == False Windows: isRelative "\\\\?\\UNC\\foo" == False Windows: isRelative "/foo" == True Windows: isRelative "\\foo" == True Posix: isRelative "test/path" == True Posix: isRelative "/test" == False Posix: isRelative "/" == False
Согласно [1]:
- "Имя UNC любого формата [никогда не является относительным]".
- "Вы не можете использовать префикс "\?" с относительным путем".
isAbsolute :: ПутьКФайлу -> Булево Исходный код
not . isRelative
isAbsolute x == not (isRelative x)
isValid :: ПутьКФайлу -> Булево Исходный код
Является ли путь к файлу допустимым, т.е. можно ли создать файл с таким именем?
isValid "" == False Posix: isValid "/random_ path:*" == True Posix: isValid x == not (null x) Windows: isValid "c:\\test" == True Windows: isValid "c:\\test:of_test" == False Windows: isValid "test*" == False Windows: isValid "c:\\test\\nul" == False Windows: isValid "c:\\test\\prn.txt" == False Windows: isValid "c:\\nul\\file" == False Windows: isValid "\\\\" == False Windows: isValid "\\\\\\foo" == False Windows: isValid "\\\\?\\D:file" == False
makeValid :: ПутьКФайлу -> ПутьКФайлу Исходный код
Принимает путь к файлу и делает его допустимым; не изменяет уже допустимые пути.
isValid (makeValid x) isValid x ==> makeValid x == x makeValid "" == "_" Windows: makeValid "c:\\already\\/valid" == "c:\\already\\/valid" Windows: makeValid "c:\\test:of_test" == "c:\\test_of_test" Windows: makeValid "test*" == "test_" Windows: makeValid "c:\\test\\nul" == "c:\\test\\nul_" Windows: makeValid "c:\\test\\prn.txt" == "c:\\test\\prn_.txt" Windows: makeValid "c:\\test/prn.txt" == "c:\\test/prn_.txt" Windows: makeValid "c:\\nul\\file" == "c:\\nul_\\file" Windows: makeValid "\\\\\\foo" == "\\\\drive" Windows: makeValid "\\\\?\\D:file" == "\\\\?\\D:\\file"
© The University of Glasgow and others
Licensed under a BSD-style license (see top of the page).
https://downloads.haskell.org/~ghc/7.10.3/docs/html/libraries/filepath-1.4.0.0/System-FilePath-Windows.html