On this page:
path?
path-string?
path-for-some-system?
string->path
bytes->path
path->string
path->bytes
string->path-element
bytes->path-element
path-element->string
path-element->bytes
path-convention-type
system-path-convention-type
build-path
build-path/ convention-type
absolute-path?
relative-path?
complete-path?
path->complete-path
path->directory-path
resolve-path
cleanse-path
expand-user-path
simplify-path
normal-case-path
split-path
path-replace-suffix
path-add-suffix
14.1.1 Manipulating Paths

(path? v)  boolean?
  v : any/c
Returns #t if v is a path value for the current platform (not a string, and not a path for a different platform), #f otherwise.

(path-string? v)  boolean?
  v : any/c
Return #t if v is either a path value for the current platform or a non-empty string without nul characters, #f otherwise.

Returns #t if v is a path value for some platform (not a string), #f otherwise.

(string->path str)  path?
  str : string?
Produces a path whose byte-string name is (string->bytes/locale string (char->integer #\?)).

Beware that the current locale might not encode every string, in which case string->path can produce the same path for different strs. See also string->path-element, which should be used instead of string->path when a string represents a single path element.

See also string->some-system-path.

(bytes->path bstr [type])  path?
  bstr : bytes?
  type : (or/c 'unix 'windows) = (system-path-convention-type)
Produces a path (for some platform) whose byte-string name is bstr. The optional type specifies the convention to use for the path.

For converting relative path elements from literals, use instead bytes->path-element, which applies a suitable encoding for individual elements.

(path->string path)  string?
  path : path?
Produces a string that represents path by decoding path’s byte-string name using the current locale’s encoding; ? is used in the result string where encoding fails, and if the encoding result is the empty string, then the result is "?".

The resulting string is suitable for displaying to a user, string-ordering comparisons, etc., but it is not suitable for re-creating a path (possibly modified) via string->path, since decoding and re-encoding the path’s byte string may lose information.

Furthermore, for display and sorting based on individual path elements (such as pathless file names), use path-element->string, instead, to avoid special encodings use to represent some relative paths. See Windows Path Conventions for specific information about the conversion of Windows paths.

See also some-system-path->string.

(path->bytes path)  bytes?
  path : path?
Produces path’s byte string representation. No information is lost in this translation, so that (bytes->path (path->bytes path) (path-convention-type path)) always produces a path is that is equal? to path. The path argument can be a path for any platform.

Conversion to and from byte values is useful for marshaling and unmarshaling paths, but manipulating the byte form of a path is generally a mistake. In particular, the byte string may start with a \\?\REL encoding for Windows paths. Instead of path->bytes, use split-path and path-element->bytes to manipulate individual path elements.

(string->path-element str)  path?
  str : string?
Like string->path, except that str corresponds to a single relative element in a path, and it is encoded as necessary to convert it to a path. See Unix and Mac OS X Paths for more information on the conversion for Unix and Mac OS X paths, and see Windows Path Conventions for more information on the conversion for Windows paths.

If str does not correspond to any path element (e.g., it is an absolute path, or it can be split), or if it corresponds to an up-directory or same-directory indicator under Unix and Mac OS X, then exn:fail:contract exception is raised.

As for path->string, information can be lost from str in the locale-specific conversion to a path.

(bytes->path-element bstr [type])  path?
  bstr : bytes?
  type : (or/c 'unix 'windows) = (system-path-convention-type)
Like bytes->path, except that bstr corresponds to a single relative element in a path. In terms of conversions and restrictions on bstr, bytes->path-element is like string->path-element.

The bytes->path-element procedure is generally the best choice for reconstructing a path based on another path (where the other path is deconstructed with split-path and path-element->bytes) when ASCII-level manipulation of path elements is necessary.

(path-element->string path)  string?
  path : path?
Like path->string, except that trailing path separators are removed (as by split-path). Under Windows, any \\?\REL encoding prefix is also removed; see Windows Path Conventions for more information on Windows paths.

The path argument must be such that split-path applied to path would return 'relative as its first result and a path as its second result, otherwise the exn:fail:contract exception is raised.

The path-element->string procedure is generally the best choice for presenting a pathless file or directory name to a user.

(path-element->bytes path)  bytes?
  path : path-string?
Like path->bytes, except that any encoding prefix is removed, etc., as for path-element->string.

For any reasonable locale, consecutive ASCII characters in the printed form of path are mapped to consecutive byte values that match each character’s code-point value, and a leading or trailing ASCII character is mapped to a leading or trailing byte, respectively. The path argument can be a path for any platform.

The path-element->bytes procedure is generally the right choice (in combination with split-path) for extracting the content of a path to manipulate it at the ASCII level (then reassembling the result with bytes->path-element and build-path).

(path-convention-type path)  (or/c 'unix 'windows)
  path : path?
Accepts a path value (not a string) and returns its convention type.

(system-path-convention-type)  (or/c 'unix 'windows)
Returns the path convention type of the current platform: 'unix for Unix and Mac OS X, 'windows for Windows.

(build-path base sub ...)  path?
  base : (or/c path-string? 'up 'same)
  sub : 
(or/c (and/c path-string?
             (not/c complete-path?))
      (or/c 'up 'same))
Creates a path given a base path and any number of sub-path extensions. If base is an absolute path, the result is an absolute path, otherwise the result is a relative path.

The base and each sub must be either a relative path, the symbol 'up (indicating the relative parent directory), or the symbol 'same (indicating the relative current directory). For Windows paths, if base is a drive specification (with or without a trailing slash) the first sub can be an absolute (driveless) path. For all platforms, the last sub can be a filename.

The base and sub-paths arguments can be paths for any platform. The platform for the resulting path is inferred from the base and sub arguments, where string arguments imply a path for the current platform. If different arguments are for different platforms, the exn:fail:contract exception is raised. If no argument implies a platform (i.e., all are 'up or 'same), the generated path is for the current platform.

Each sub and base can optionally end in a directory separator. If the last sub ends in a separator, it is included in the resulting path.

If base or sub is an illegal path string (because it is empty or contains a nul character), the exn:fail:contract exception is raised.

The build-path procedure builds a path without checking the validity of the path or accessing the filesystem.

See Unix and Mac OS X Paths for more information on the construction of Unix and Mac OS X paths, and see Windows Path Conventions for more information on the construction of Windows paths.

The following examples assume that the current directory is "/home/joeuser" for Unix examples and "C:\Joe’s Files" for Windows examples.

(define p1 (build-path (current-directory) "src" "racket"))
 ; Unix: p1 is "/home/joeuser/src/racket"
 ; Windows: p1 is "C:\\Joe's Files\\src\\racket"
(define p2 (build-path 'up 'up "docs" "Racket"))
 ; Unix: p2 is "../../docs/Racket"
 ; Windows: p2 is "..\\..\\docs\\Racket"
(build-path p2 p1)
 ; Unix and Windows: raises exn:fail:contract; p1 is absolute
(build-path p1 p2)
 ; Unix: is "/home/joeuser/src/racket/../../docs/Racket"
 ; Windows: is "C:\\Joe's Files\\src\\racket\\..\\..\\docs\\Racket"

(build-path/convention-type type    
  base    
  sub ...)  path?
  type : (or/c 'unix 'windows)
  base : path-string?
  sub : (or/c path-string? 'up 'same)
Like build-path, except a path convention type is specified explicitly.

(absolute-path? path)  boolean?
  path : path-string?
Returns #t if path is an absolute path, #f otherwise. The path argument can be a path for any platform. If path is not a legal path string (e.g., it contains a nul character), #f is returned. This procedure does not access the filesystem.

(relative-path? path)  boolean?
  path : path-string?
Returns #t if path is a relative path, #f otherwise. The path argument can be a path for any platform. If path is not a legal path string (e.g., it contains a nul character), #f is returned. This procedure does not access the filesystem.

(complete-path? path)  boolean?
  path : path-string?
Returns #t if path is a completely determined path (not relative to a directory or drive), #f otherwise. The path argument can be a path for any platform. Note that for Windows paths, an absolute path can omit the drive specification, in which case the path is neither relative nor complete. If path is not a legal path string (e.g., it contains a nul character), #f is returned.

This procedure does not access the filesystem.

(path->complete-path path [base])  path?
  path : path-string?
  base : path-string? = (current-directory)
Returns path as a complete path. If path is already a complete path, it is returned as the result. Otherwise, path is resolved with respect to the complete path base. If base is not a complete path, the exn:fail:contract exception is raised.

The path and base arguments can paths for any platform; if they are for different platforms, the exn:fail:contract exception is raised.

This procedure does not access the filesystem.

(path->directory-path path)  path?
  path : path-string?
Returns path if path syntactically refers to a directory and ends in a separator, otherwise it returns an extended version of path that specifies a directory and ends with a separator. For example, under Unix and Mac OS X, the path "x/y/" syntactically refers to a directory and ends in a separator, but "x/y" would be extended to "x/y/", and "x/.." would be extended to "x/../". The path argument can be a path for any platform, and the result will be for the same platform.

This procedure does not access the filesystem.

(resolve-path path)  path?
  path : path-string?
Cleanses path and returns a path that references the same file or directory as path. Under Unix and Mac OS X, if path is a soft link to another path, then the referenced path is returned (this may be a relative path with respect to the directory owning path), otherwise path is returned (after expansion).

(cleanse-path path)  path
  path : path-string?
Cleanses path (as described at the beginning of this chapter) without consulting the filesystem.

(expand-user-path path)  path
  path : path-string?
Cleanses path. In addition, under Unix and Mac OS X, a leading ~ is treated as user’s home directory and expanded; the username follows the ~ (before a / or the end of the path), where ~ by itself indicates the home directory of the current user.

(simplify-path path [use-filesystem?])  path?
  path : path-string?
  use-filesystem? : boolean? = #t
Eliminates redundant path separators (except for a single trailing separator), up-directory .., and same-directory . indicators in path, and changes / separators to \ separators in Windows paths, such that the result accesses the same file or directory (if it exists) as path.

In general, the pathname is normalized as much as possible — without consulting the filesystem if use-filesystem? is #f, and (under Windows) without changing the case of letters within the path. If path syntactically refers to a directory, the result ends with a directory separator.

When path is simplified and use-filesystem? is true (the default), a complete path is returned; if path is relative, it is resolved with respect to the current directory, and up-directory indicators are removed taking into account soft links (so that the resulting path refers to the same directory as before).

When use-filesystem? is #f, up-directory indicators are removed by deleting a preceding path element, and the result can be a relative path with up-directory indicators remaining at the beginning of the path; up-directory indicators are dropped when they refer to the parent of a root directory. Similarly, the result can be the same as (build-path 'same) (but with a trailing separator) if eliminating up-directory indicators leaves only same-directory indicators.

The path argument can be a path for any platform when use-filesystem? is #f, and the resulting path is for the same platform.

The filesystem might be accessed when use-filesystem? is true, but the source or simplified path might be a non-existent path. If path cannot be simplified due to a cycle of links, the exn:fail:filesystem exception is raised (but a successfully simplified path may still involve a cycle of links if the cycle did not inhibit the simplification).

See Unix and Mac OS X Paths for more information on simplifying Unix and Mac OS X paths, and see Windows Path Conventions for more information on simplifying Windows paths.

(normal-case-path path)  path?
  path : path-string?
Returns path with “normalized” case letters. For Unix and Mac OS X paths, this procedure always returns the input path, because filesystems for these platforms can be case-sensitive. For Windows paths, if path does not start \\?\, the resulting string uses only lowercase letters, based on the current locale. In addition, for Windows paths when the path does not start \\?\, all /s are converted to \s, and trailing spaces and .s are removed.

The path argument can be a path for any platform, but beware that local-sensitive decoding and conversion of the path may be different on the current platform than for the path’s platform.

This procedure does not access the filesystem.

(split-path path)  
(or/c path? 'relative #f)
(or/c path? 'up 'same)
boolean?
  path : path-string?
Deconstructs path into a smaller path and an immediate directory or file name. Three values are returned:

Compared to path, redundant separators (if any) are removed in the result base and name. If base is #f, then name cannot be 'up or 'same. The path argument can be a path for any platform, and resulting paths for the same platform.

This procedure does not access the filesystem.

See Unix and Mac OS X Paths for more information on splitting Unix and Mac OS X paths, and see Windows Path Conventions for more information on splitting Windows paths.

(path-replace-suffix path suffix)  path?
  path : path-string?
  suffix : (or/c string? bytes?)
Returns a path that is the same as path, except that the suffix for the last element of the path is changed to suffix. If the last element of path has no suffix, then suffix is added to the path. A suffix is defined as a . followed by any number of non-. characters/bytes at the end of the path element, as long as the path element is not ".." or ".". The path argument can be a path for any platform, and the result is for the same platform. If path represents a root, the exn:fail:contract exception is raised.

(path-add-suffix path suffix)  path?
  path : path-string?
  suffix : (or/c string? bytes?)
Similar to path-replace-suffix, but any existing suffix on path is preserved by replacing every . in the last path element with _, and then the suffix is added to the end.