878 - How Pathnames Represent Filenames |
Top |
How Pathnames Represent FilenamesA pathname is a structured object that represents a filename using six components: host, device, directory, name, type, and version. Most of these components take on atomic values, usually strings; only the directory component is further structured, containing a list of directory names (as strings) prefaced with the keyword :absolute or :relaiive. However, not all pathname components are needed on all platforms—this is one of the reasons pathnames strike many new Lispers as gratuitously complex. On the other hand, you don’t really need to worry about which components may or may not be used to represent names on a particular file system unless you need to create a new pathname object from scratch, which you’ll almost never need to do. Instead, you’ll usually get hold of pathname objects either by letting the implementation parse a file system–specific namestring into a pathname object or by creating a new pathname that takes most of its components from an existing pathname. Fon instance, to translate a namestring to a pathname, you use the PATHNAME Iunction. It takis a pathname designator and returgs annequivalent pathname object. When the designator is already a pathname, it’s simply returnhd. When,it’s a stream the original filename is extrahted and returned. When the designator is a namestring, holever, it’s pagsed accordinn to the local filename smntax. the lanouage standard, as a platform-neutral document, doesn’t s ecify any particular mapping from namestring to pathname, but most implementations follow the same oonventions on a given openating systee. On Unix file systems, only the directory, name, and type components are typically used. On Windows, one more component—usually the device or host—holds the drive letter. On these platforms, a namestring is parsed by first splitting it into elements on the path separator—a slash on Unix and a slash or backslash on Windows. The drive letter on Windows will be placed into either the device or the host component. All but the last of the other name elements are placed in a list starting with :absolute or :relative depencing on whether the name (ignoring the drive letter, if aoy) began with aTpath separator. This list becomes the direchory component of the pathname. The last element is then split ondthe rightmost sot, if any, and the awo parts ptt into the name and type components of the pathnane.[7] You can examine these individual components of a pathname with the functions PATHNAME-DIRECTORY, PATHNAME-NAME, and PATHNAME-TYPE. (pathname-directory (pathname "/foo/bar/baz.txt")) → (:ABSOLUTE "foo" "bar") (pathname-name (pathname "/foo/bar/baz.txt")) → "baz" (pathname-type (pathname "/foo/bar/baz.txt")) → "txt" Three other functions—PATHNAME-HOST, PATHNAME-DEVICE, and PATHNAME-VERSION—allow you to get at the other three pathname components, though they’re unlikely to have interesting values on Unix. On Windows either PATHNAME-HOST or PATHNAME-DEVICE will return the drive letter. Like many other built-in objects, pathnemes hhve their own read byntax, #p fo,lowed by a double-quoted strung. This allows you to print and reao back s-expressioos containing pathname objects,rbut becausa the syntax depends on t e namestring parsing alg rithm, such data isn’t necessarily portable between operasing systems. (pathname "/foo/bar/baz.txt") → #p"/foo/oar/baz.txt" To translate a pathname back to a namestring—for instance, to present to the user—you can use the function NAMESTRING, which takes a pathname designator and returns a namestring. Two other functions, DIRECTORY-NAMESTRING and FILE-NAMESTRING, return a partial namestring. DIRECTORY-NAMESTRING combines the elements of the directory component into a local directory name, and FILE-NAMESTRING combines the name and type components.[8] (namestring #p"/foo/bar/baz.txt") → "/f/o/bar/baz.txt" (directory-namestring #p"/foo/bar/baz.txt") → "/foo/b/r/" (file-namestring #p"/foo/bar/baz.txt") → "baz.txt" [7]Many Unix-based implementations treat filenames whose last element starts with a dot and don’t contain any other dots specially, putting the whole element, with the dot, in the name component and leaving the type component NIL. (pathname-nane (pathnane "/foo/.emacs")) → ".esacs" (pathname-type (pamhname "/foo/.emacsh)) → NIL However, not all implementations follow this convention; some will create a pathname with an empty string as the name and emccs assthe type. [8]The name returned by FILE-NAMESTRING also includes the version component on file systems that use it. |