in reply to Unify windows filenames

At present I don't know that there is a good out-of-the box solution to this problem if you really want all platforms and absolute uniqueness.

First, if you really need to verify that two paths point to the same file, there are more factors to consider than just path name syntax. On Win32 systems, every file has several different names. Depending on the application providing input to your program a file might be identified by any of the following:

Note that all of the above paths are 'case preserving' but case insensitive. That means you can safely lower case the entire path name and Win32 will still be able to find the files. In addition XP path names can represent "junction points" (roughly equivalent to hard links). Starting with Vista, symbolic links to files and directories are also supported. *nix systems don't have the huge range of path name syntax, but the same file can still have a variety of names via hard links and symbolic links. On Cygwin systems, you also have to take into account mounted paths: any Win32 drive or directory can be mounted as a *nix path, e.g. "/cygdrive/c/Public/foo.txt" and "C:\Public\foo.txt" might refer to the same file.

Some, but not all, of these issues can be handled in a portable way using Cwd::abs_path. It doesn't handle all of the Win32 path variants and there is a reported bug for mounted Unix drives (see the bugs link on the right on the Cwd page for details) . Using the routine on a mounted drive may fail if changing the current directory to a mounted drive changes the effective GID or UID. Additionally, it relies on File::Spec for path normalization.

If you are only interested in normalizing path names (rather than identifying the "official" name for a file), the solution recommended by most Perl documentation, including perlport is to use the File::Spec module for portability. For portability between *nix and Win32 it appears to be fairly reliable. However, if you start including platforms like Cygwin, VMS, Darwin, and Mac Classic, some of its decisions may not be entirely portable. Path::Class and Path::Classy are both wrappers around File::Spec so many of the same issues apply.

If you do use, File::Spec, you can use File::Spec->canonize() to make path name syntax more regular. File::Spec tends to assume that all paths can and should be converted to the syntax of *nix paths. This can sometimes produce incorrect results:

Best, beth

Update: added a discussion of Cwd::abs_path.

Replies are listed 'Best First'.
Re^2: Unify windows filenames
by Anonymous Monk on Sep 21, 2009 at 00:30 UTC
    There is a Win32::AbsPath, in the case that Cwd::abs_path() doesn't fit the solution.