Copying symlinks

Posted: April 15, 2013 in NIO, Symlinks

JDK7 offers a whole new set of methods to work with symbolic links. This was in pre-JDK7 times pretty difficult and often you had to execute barebone copy statements through the runtime. There is one method which I missed in the API. You can open or follow the link, or test whether your file is a link, but you cannot “copy” the link itself. You need to resolve the original link and create a new link as illustrated in the class below.

The class could surely be optimized, but it gives you an idea on how the symbolic links function.

public class LinkFileVisitor extends SimpleFileVisitor<Path> {

    private Path fromPath;

    private Path toPath;

    public LinkFileVisitor(final Path fromPath, final Path toPath) {
        this.fromPath = fromPath;
        this.toPath = toPath;

  public static void copy(final Path from, final Path to)
            throws IOException {

        // make sure it is a directory
        if (!Files.isDirectory(from)) {
            throw new IllegalArgumentException(
                    String.format("%s is not a directory", from.toString()));

        Files.walkFileTree(from, new HashSet(),
                Integer.MAX_VALUE, new LinkFileVisitor(from, to));


    public FileVisitResult preVisitDirectory(final Path dir,
            final BasicFileAttributes attrs)
            throws IOException {
        Path targetPath = toPath.resolve(fromPath.relativize(dir));
        if (!Files.exists(targetPath)) {
        return FileVisitResult.CONTINUE;

    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
            throws IOException {
         if (Files.isSymbolicLink(file)) {
            Path link = toPath.resolve(fromPath.relativize(file));
            if (Files.exists(link, LinkOption.NOFOLLOW_LINKS)) {
            Files.createSymbolicLink(link, Files.readSymbolicLink(file));
        } else {
            Files.copy(file, toPath.resolve(fromPath.relativize(file)),
        return FileVisitResult.CONTINUE;

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s