Paths - file name, URLs, and URIs

A Path is the name of a file or some other resource. The path mechanism provides a layer of abstraction, so you can use the same functions on either a filename or a URL/URI. Functions that in standard Scheme take a filename have been generalized to take a path or a path string, as if using the path function below. For example:

(open-input-file "http://www.gnu.org/index.html")
(open-input-file (URI "ftp://ftp.gnu.org/README"))

Type: path

A general path, which can be a filename or a URI. It can be either a filename or a URI. Represented using the abstract Java class gnu.kawa.io.Path.

Coercing a value to a Path is equivalent to calling the path constructor documented below.

Constructor: path arg

Coerces the arg to a path. If arg is already a path, it is returned unchanged. If arg is a java.net.URI, or a java.net.URL then a URI value is returned. If arg is a java.io.File, a filepath value is returned. Otherwise, arg can be a string. A URI value is returned if the string starts with a URI scheme (such as "http:"), and a filepath value is returned otherwise.

Predicate: path? arg

True if arg is a path - i.e. an instance of a gnu.kawa.io.Path.

Procedure: current-path [new-value]

With no arguments, returns the default directory of the current thread as a path. This is used as the base directory for relative pathnames. The initial value is that of the user.dir property as returned by (java.lang.System:getProperty "user.dir").

If a new-value argument is given, sets the default directory:

(current-path "/opt/myApp/")

A string value is automatically converted to a path, normally a filepath.

Alternatively, you can change the default using a setter:

(set! (current-path) "/opt/myApp/")

Since current-path is a parameter object, you can locally change the value using parameterize.

Type: filepath

The name of a local file. Represented using the Java class gnu.kawa.io.FilePath, which is a wrapper around java.io.File.

Predicate: filepath? arg

True if arg is a filepath - i.e. an instance of a gnu.kawa.io.FilePath.

Type: URI

A Uniform Resource Indicator, which is a generalization of the more familiar URL. The general format is specified by RFC 2396: Uniform Resource Identifiers (URI): Generic Syntax. Represented using the Java class gnu.kawa.io.URIPath, which is a wrapper around java.net.URI. A URI can be a URL, or it be a relative URI.

Predicate: URI? arg

True if arg is a URI - i.e. an instance of a gnu.kawa.io.URIPath.

Type: URL

A Uniform Resource Locator - a subtype of URI. Represented using the Java class gnu.kawa.io.URLPath, which is a wrapper around a java.net.URL, in addition to extending gnu.kawa.io.URIPath.

Extracting Path components

Procedure: path-scheme arg

Returns the “URI scheme” of arg (coerced to a path) if it is defined, or #f otherwise. The URI scheme of a filepath is "file" if the filepath is absolute, and #f otherwise.

(path-scheme "http://gnu.org/") ⇒ "http"

Procedure: path-authority arg

Returns the authority part of arg (coerced to a path) if it is defined, or #f otherwise. The “authority” is usually the hostname, but may also include user-info or a port-number.

(path-authority "http://me@localhost:8000/home") ⇒ "me@localhost:8000"

Procedure: path-host arg

Returns the name name part of arg (coerced to a path) if it is defined, or #f otherwise.

(path-host "http://me@localhost:8000/home") ⇒ "localhost"

Procedure: path-user-info arg

Returns the “user info” of arg (coerced to a path) if it is specified, or #f otherwise.

(path-host "http://me@localhost:8000/home") ⇒ "me"

Procedure: path-port arg

Returns the port number of arg (coerced to a path) if it is specified, or -1 otherwise. Even if there is a default port associated with a URI scheme (such as 80 for http), the value -1 is returned unless the port number is explictly specified.

(path-host "http://me@localhost:8000/home") ⇒ 8000
(path-host "http://me@localhost/home") ⇒ -1

Procedure: path-file arg

Returns the “path component” of the arg (coerced to a path). (The name path-path might be more logical, but it is obviously a bit awkward.) The path component of a file name is the file name itself. For a URI, it is the main hierarchical part of the URI, without schema, authority, query, or fragment.

(path-file "http://gnu.org/home/me.html?add-bug#body") ⇒ "/home/me.html"

Procedure: path-directory arg

If arg (coerced to a path) is directory, return arg; otherwise return the “parent” path, without the final component.

(path-directory "http://gnu.org/home/me/index.html#body")
  ⇒ (path "http://gnu.org/home/me/")
(path-directory "http://gnu.org/home/me/")
  ⇒ (path "http://gnu.org/home/me/")

(path-directory "./dir") (path "./dir") if dir is a directory, and (path ".") otherwise.

Procedure: path-parent arg

Returns the “parent directory” of arg (coerced to a path). If arg is not a directory, same as path-directory arg.

(path-parent "a/b/c") ⇒ (path "a/b")
(path-parent "file:/a/b/c") ⇒ (path "file:/a/b/c")
(path-parent "file:/a/b/c/") ⇒ (path "file:/a/b/")

Procedure: path-last arg

The last component of path component of arg (coerced to a path). Returns a substring of (path-file arg). If that string ends with ‘/’ or the path separator, that last character is ignored. Returns the tail of the path-string, following the last (non-final) ‘/’ or path separator.

(path-last "http:/a/b/c") ⇒ "c"
(path-last "http:/a/b/c/") ⇒ "c"
(path-last "a/b/c") ⇒ "c"

Procedure: path-extension arg

Returns the “extension” of the arg (coerced to a path).

(path-extension "http://gnu.org/home/me.html?add-bug#body") ⇒ "html"
(path-extension "/home/.init") ⇒ #f

Procedure: path-query arg

Returns the query part of arg (coerced to a path) if it is defined, or #f otherwise. The query part of a URI is the part after ‘?’.

(path-query "http://gnu.org/home?add-bug") ⇒ "add-bug"

Procedure: path-fragment arg

Returns the fragment part of arg (coerced to a path) if it is defined, or #f otherwise. The fragment of a URI is the part of after ‘#’.

(path-query "http://gnu.org/home#top") ⇒ "top"

Procedure: resolve-uri uri base

Returns a uri unchanged if it is an absolute URI. Otherwise resolves it against a base URI base, which is normally (though not always) absolute.

This uses the algorithm specifyed by RFC-3986 (assuming base is absolute), unlike the obsolete RFC-2396 algorithm used by java.net.URI.resolve.