Channels ▼

Eric Bruno

Dr. Dobb's Bloggers

More on Java 7 File IO

September 12, 2011

A reader of my previous blog on Java SE 7's File IO enhancements asked how symbolic links are handled in an OS-agnostic way. Good question! Let's examine that now. Recall Java 7's new Path class, and how it abstracts the details of the path to a directory or file, as in this example:

Path path = FileSystems.getDefault().getPath(".", name);
InputStream in = Files.newInputStream(path);
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
List<String> lines = new ArrayList<>();
String line = null;
while ( (line = reader.readLine()) != null )
// ...

What my summary left out is that the class Path represents not only files and directories, but links to files and directories, symbolic or otherwise. In fact, the Path class detects and handles links automatically, without requiring you to do anything specific when one is encountered in your application. However, you do have options available on how to handle symbolic links when they occur, and you can also create new links in Java for file systems that support them.

Soft or Hard Link?

Like ice-cream, links come in two main varieties: soft (or symbolic) and hard. What's the difference? Symbolic links refer to other files or directories and are generally transparent to applications that use them. They are simply pointers to actual files. Operating systems are usually very lenient with how they are created and used, and therefore problems can arise. One example is a symbolic link that forms a circular reference: An application that recursively walks a directory tree that contains a symbolic link that points back to a higher level in the very same tree will recurse infinitely.

A hard link is more restrictive, and often resolves many of the issues related to soft links. However, because of these restrictions, they are generally used less often than soft links. Hard links have the following restrictions:

  • The target of the link must exist

  • The target cannot be a directory

  • The target must exist on the same partition or volume

Java SE 7 and Links

The Java 7 Path and Files classes work with both soft (symbolic) and hard links. For example, to determine if a Path is a symbolic link, you pass it to the Files.isSymbolicLink() method:

// links to /logs/myapplogs/myapplog
Path logs = FileSystems.getDefault().getPath("~/MyApp/MyAppLog"); 
boolean isSoftLink = Files.isSymbolicLink(logs);

To resolve a symbolic link, read the output (yet another Path object) of a call to Files.readSymbolicLink(), where the Path object representing the link is passed as a parameter:

Path target = Files.readSymbolicLink(logs);
System.out.println("MyApp log file resides here: " + target.toString() );

To create a symbolic link (not supported on Windows), you use the aptly named Files.createSymbolicLink() method, and pass two Path objects. The first represents the link to be created, and the second is the path to the actual target file or directory:

// the link to be created
Path link = FileSystems.getDefault().getPath("~/MyApp/MyAppLog"); 

// the target file (doesn't really need to exist)
Path target = FileSystems.getDefault().getPath("/logs/myapplogs/myapplog"); 
Files.createSymbolicLink(link, target);

You can create a hard link (which is supported by Windows) but the target file must exist in this case:

// the link to be created
Path hardLink = FileSystems.getDefault().getPath("/Program Files/MyApp/MyAppLog"); 

// the target file (MUST EXIST!!)
Path target = FileSystems.getDefault().getPath("/WINDOWS/Temp/myapplogs/myapplog"); 
Files.createLink(hardLink, target);

In any of these examples, if the underlying OS does not support symbolic and/or hard links, or if you violate one of the restrictions of hard links, you will get an IOException at runtime. Therefore, be ready to handle this situation gracefully in your code.

Diving deeper into Java SE 7's File IO APIs, you can use the FileVisitor interface to determine if and how links are followed, when to avoid them (i.e. when deleting files), and detect if a circular reference exists.

For more information on creating, detecting, and using links in your application, read the Java 7 Tutorial, or the Java 7 APIs.

Happy coding!

Related Reading

More Insights

Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.