Filepaths in julia with FilePathsBase

Type Based Path Operation in Julia One of Julia's famous features is its type system. However, the julia base treat files and paths as strings. FilePathsBase.jl and FilePaths provide a type based approach for filesystems in Julia.

FilePathsBase

Quick start

Note

  • /: concat FilePaths and Strings, more expressive than using * for path join, e.g.: p"/path/to" / "prefix" * ".jl";

  • cwd(): similar to pwd(), but outputs FilePath type

  • stat(): stat files with input of FilePath type

  • warklpath(): walk through FilePaths, return array of paths;

  • relative(P1<:AbstractPath, P2<:AbstractPath): return paths of P1 relative to P2;

  • absolute(P<:AbstractPath): return the absolute path of P1;

  • islink(P): check if P is a link;

  • canonicalize(P): get the real path of symlink P

  • parents(P): get all parent dirs of P, returns an Array{AbstractPath}

  • mktemp(Systempath)/mktempdir(Systempath)

  • sync([f::Fucntion,] src, dst; delete=false, overwrite=true): recursively copy new and updated files from src to dst, also could apply function;

  • mode(P): return the Mode of P, in Mode type: "Mode("-rw-rw-rw-")";

  • chmod(P, "+x"),m::Mode + executeable(:ALL); m - readable(:ALL): change mode

  • rm(P; recursive=true);

  • exists(P)

🥑 Some design throughts and FAQs

  • FilePathsBase.jl or FilePaths.jl: FilePathsBase has less dependency, thus suitable for low level development, FilePaths extends FilePathsBase.jl at the cost of extra dependencies, thus more suitable for scripts/app-level packages.

  • Write code that works for both Strings and Paths:

  • Don't overly constrain your argument types;

  • Avoid manual string manipulations (eg. match, replace).

  • Stick to the overlapping base filesystem aliases (eg. joinpath vs /, normpath vs normalize).

  • @convert: a macro for method convertions.

Ref List

Operations

A table of common operations with Filesystem and FilePathsBase.

FilesystemFilePathsBase.jl
"/home/user/docs"p"/home/user/docs"
Path()
pwd()pwd(SystemPath) or cwd()
homedir()homedir(SystemPath) or home()
cd()cd()
joinpath()/
basename()basename()
hasparent, parents, parent
splitextsplitext
filename
extension
extensions
ispathexists
realpathcanonicalize
normpathnormalize
abspathabsolute
relpathrelative
statstat
lstatlstat
filemodemode
filesizefilesize
mtimemodified
ctimecreated
isdirisdir
isfileisfile
islinkislink
issocketissocket
isfifoisfifo
ischardevischardev
isblockdevisblockdev
isexecutable (deprecated)isexecutable
iswritable (deprecated)iswritable
isreadable (deprecated)isreadable
ismountismount
isabspathisabsolute
splitdrive()[1]drive
root (property)
split(p, "/")segments (property)
expanduserexpanduser
mkdirmkdir
mkpathN/A (use mkdir)
symlinksymlink
cpcp
mvmv
downloaddownload
readdirreaddir
readpath
walkpathwalkpath
rmrm
touchtouch
tempname()tempname(::Type{<:AbstractPath}) (or tmpname)
tempdir()tempdir(::Type{<:AbstractPath}) (or tmpdir)
mktemp()mktemp(::Type{<:AbstractPath}) (or mktmp)
mktempdir()mktempdir(::Type{<:AbstractPath}) (or mktmpdir)
chmodchmod (recursive unix-only)
chown (unix only)chown (unix only)
readread
writewrite
@__DIR__@__PATH__
@__FILE__@__FILEPATH__

Aliases

A slightly reduced list of operations/aliases that will work with both strings and path types. The Filesystem and FilePathsBase columns indicate what type will be returned from each each library. As you'd expect, most return types match the input argument(s).

Function NameFilesystemFilePathsBase
cdAbstractStringAbstractPath
joinpathAbstractStringAbstractPath
basenameAbstractStringAbstractString
splitext(AbstractString, AbstractString)(AbstractPath, AbstractString)
ispathBoolBool
realpathAbstractStringAbstractPath
normpathAbstractStringAbstractPath
abspathAbstractStringAbstractPath
relpathAbstractStringAbstractPath
statStatStructFilePathsBase.Status
lstatStatStructFilePathsBase.Status
filemodeUInt64FilePathsBase.Mode
filesizeInt64Int64
mtimeFloat64Float64
ctimeFloat64Float64
isdirBoolBool
isfileBoolBool
islinkBoolBool
issocketBoolBool
isfifoBoolBool
ischardevBoolBool
isblockdevBoolBool
ismountBoolBool
isabspathBoolBool
expanduserAbstractStringAbstractPath
mkdirAbstractStringAbstractPath
mkpathAbstractStringAbstractPath
symlinkNothingNothing
cpAbstractStringAbstractPath
mvAbstractStringAbstractPath
downloadAbstractStringAbstractPath
readdirAbstractStringAbstractString
rmNothingNothing
touchAbstractStringAbstractPath
chmodAbstractStringAbstractPath
chownAbstractStringAbstractPath
read(fp, T)TT
writeInt64Int64

FilePaths

FilePaths extends FilePathsBase with several useful functions:

📘 Functions in `FilePaths` glob: extend global match package Glob to support FilePaths

julia

glob(pattern, P::T) where T <: AbstractPath

julia

URI: extend URIparser packge URI to support FilePaths (I have not used URI)

@compat: write string and AbstractPath compatible codes:

julia

FilePaths.@compat function myrelative(x::AbstractPath, y::AbstractPath)
    return relative(x, y)
end

# the function myrelative could deal with AbstractPaths and Strings:
myrelative(cwd(), home())
myrelative(pwd(), homedir())
myrelative(pwd(), home())
# all return in AbstractPath type

julia

More about Mode in FilePathsBase

Mode type provides abstraction for working with posix file permissions

julia

struct Mode
    m::UInt64
end

# user groups symbols:
:ALL
:USER
:GROUP
:OTHER

# dispatch base functions for dealing with Mode:
+, -, Base.oct, 
isdir, isfile, islink, issocket, isfifo, ischardev, isblockdev
iswritable, isreadable, isexecutable # isexecutable is newly definde in FilePathsBase

# function alias
executable(usr_grps::Symbol...) = Mode(EXEC, usr_grps...)
readable(usr_grps::Symbol...) = Mode(READ, usr_grps...)
writable(usr_grps::Symbol...) = Mode(WRITE, usr_grps...)

julia