JDK-6358641 : File.getNormalized{File,Path}() which does not traverse symlinks unlike getCanonical{File,Path}()
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.io
  • Affected Version: 5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2005-12-02
  • Updated: 2010-05-11
  • Resolved: 2009-02-16
Related Reports
Duplicate :  
Relates :  
Description
I would like to request a method to be added to java.io.File:

public File getNormalizedFile();

Similarly,

public String getNormalizedPath();

could be added for symmetry with existing methods.

Its effect would be similar to getCanonicalPath(), but would never attempt to traverse symlinks on Unix (or similar structures on other operating systems). It might need to throw IOException for the Windows implementation in order to correct case on existing files (not, I believe, for the Unix implementation).

The justification is that it is often desirable to have a "cleaned-up" form of a file path that you can use in an application, for which getCanonicalFile() could be used if it were not for the symlink behavior. Consider an application which asks the user for a path to some file or dir to be used as a project or something whose path should be persisted, written to other files, etc. Suppose the user Bob has an NFS home dir managed by a clever sysadmin (who does not use OS-level logical volume management), so that

/home/bob -> /mnt/fs0013/users/bob

on a particular day. If the application stores a canonicalized path such as

/mnt/fs0013/users/bob/stuff

in some settings file, it will get broken if the disk is ever swapped out for a new one when Bob is logged out!

Similarly, an installation of software like

/opt/someprogram -> /opt/someprogram-1.0.5

is fine until your Java app stores "/opt/someprogram-1.0.5" in its preferences somewhere and the user upgrades to 1.0.6.

Bug #4906607 requests non-canonicalizing behavior for JFileChooser. In that bug, I suggested a workaround of using URI.normalize, but that is not very complete - there are other cases you need to handle. This sort of platform-specific code seems like it belongs in the JRE so it can be properly implemented by Sun and licensees.

Consider the NetBeans API FileUtil.normalizeFile:

http://www.netbeans.org/source/browse/~checkout~/openide/fs/src/org/openide/filesystems/FileUtil.java

Note the varying behaviors for Windows, Unix, and Mac OS X, according to existence of symlinks, case sensitivity, etc.

Similarly, Apache Ant has a somewhat simpler FileUtils.normalize:

http://svn.apache.org/repos/asf/ant/core/trunk/src/main/org/apache/tools/ant/util/FileUtils.java

Also Googling "normalize java.io.File" shows some other suspects:

http://www.dpml.net/api/checkstyle/3.5/com/puppycrawl/tools/checkstyle/Checker.html#normalize(java.lang.String)
http://www.keelframework.org/release/2.1-dev/javadoc/org/apache/excalibur/source/SourceUtil.html#normalize(java.lang.String)

Looks like this used to have such a method:

http://jakarta.apache.org/commons/io/api-1.0/org/apache/commons/io/FileUtils.html

I'm not sure if (the non-API) java.io.FileSystem.normalize(String) is related - its Javadoc is too brief.

Comments
EVALUATION This feature has been addressed by the new file system API defined by JSR-203.
16-02-2009