Saturday, April 22, 2023

How to create Soft and Hard Links in Java? Files + Path + Java NIO Example

Hello guys, not many people know that Java NIO File API also allows you to create links in Java. Many of Java programmer are familiar with ln command in Linux which is used to create soft and hard link but you can also do that using Java File API. 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?

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 recurs 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
And, if you are wondering difference between hard link and soft link, here is a nice diagram which clearly explains the difference between hard link and soft link. In case of hard link, it directly point to the data in the disc while soft link points to the file object. 

How to create Soft and Hard Links in Java? Files + Path + Java NIO Example




Java Program to create Hard and Soft using Files and Path with Example

Here is our complete Java Program to create links in Java using Files and Path class or Java NIO Package. This program will work fine after JDK 7 onwards because this feature was introduced in Java NIO on Java 7.

Before running this Java program, here is how my file system was looking like :
 
javin@workstation2  ~/Test
$ ls -lrt
total 13666
----------+ 1 javin None      4056 Feb 17 15:54 data.txt
 
javin@workstation2 /cygdrive/d/JavaWorkspace/Test
$ ln -s data.txt link_data.txt
 
javin@workstation2 /cygdrive/d/JavaWorkspace/Test
$ ls -lrt
total 13666
----------+ 1 javin None      4056 Feb 17 15:54 data.txt
lrwxrwxrwx  1 javin None         8 Feb 24 18:41 link_data.txt -> data.txt
 
And, now let's see the program and output to understand it better:

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
 
/**
* How to create soft and hard links in Java. From JDK 1.7, its possible to
* create symbolic links in Java. Path class from java.nio.file class supports
* both soft and hard links.
*
* @author Javin Paul
*/
public class Testing {
 
    public static void main(String args[]) {
 
        // Checking if a PATH is symbolic link or not
        // Remember Windows doesn't support symbolic links
        // so it will always return false
        Path data = FileSystems.getDefault().getPath("~/test/data.txt");
        boolean isSoftLink = Files.isSymbolicLink(data);
        System.out.printf("Does Path : %s is a soft link? %b %n", data, isSoftLink);
 
        Path link = FileSystems.getDefault().getPath("~/test/link_data.txt");
        boolean isLink = Files.isSymbolicLink(link);
        System.out.printf("Does Path : %s is a soft link? %b %n", link, isLink);
 
        // Creating Hard link in Windows, target file must exists
        // the link to be created
        Path hardLink = FileSystems.getDefault()
                            .getPath("D:/Eclipse_workspace/Test/hardlink.txt");
        Path target = FileSystems.getDefault()
                            .getPath("D:/Eclipse_workspace/Test/data.txt");
        try {
            Path newlink = Files.createLink(hardLink, target);
        } catch (IOException e) {
            e.printStackTrace();
        }
 
    }
 
}
 
Output:
Does Path : ~\test\data.txt is a soft link? false
Does Path : ~\test\link_data.txt is a soft link? false


Things to note about Links and Files in Windows

1) Windows doesn't support soft links, but hard link is supported by Windows
2) The Java 7 Path and Files classes work with both soft (symbolic) and hard links.
3) to determine if a Path is a symbolic link, you pass it to the Files.isSymbolicLink() method
 
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.
 
 By the way, if hard link already exists then it will throw following exception
java.nio.file.FileAlreadyExistsException: D:\temp\hardlink.txt -> D:\temp\data.txt
               at sun.nio.fs.WindowsException
.translateToIOException(WindowsException.java:81)
               at sun.nio.fs.WindowsException
.rethrowAsIOException(WindowsException.java:97)
               at sun.nio.fs.WindowsFileSystemProvider
.createLink(WindowsFileSystemProvider.java:600)
               at java.nio.file.Files.createLink(Files.java:1037)
 
 
 
To create a symbolic link (not supported on Windows), you use the  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 softlink = FileSystems.getDefault().getPath("~/new.txt");
 
// the target file (doesn't really need to exist)
Path target = FileSystems.getDefault().getPath("~/old.txt");
Files.createSymbolicLink(link, target);


That's all about how to create hard and soft link using Files class in Java. This is one of the interesting feature of Java API and I think every Java Programmer should know it. Files is anyway a very useful and essential class and you should learn it as part of your Java learning journey. 

No comments:

Post a Comment