Create a Symbolic Link with Java – 用Java创建一个符号链接

最后修改: 2018年 7月 8日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’ll explore different ways of creating a symbolic link in Java using the NIO.2 API, and explore the differences between hard and soft file links.

在本教程中,我们将探讨使用NIO.2 API在Java中创建符号链接的不同方式,并探讨硬文件和软文件链接之间的区别。

2. Hard vs Soft/Symbolic Links

2.硬性与软性/象征性链接

First, let’s define what file links are and what is their expected behavior. A file link is a pointer that transparently references a file stored in the file system.

首先,让我们定义一下什么是文件链接,以及它们的预期行为是什么。文件链接是一个指针,它透明地引用存储在文件系统中的文件

A common misunderstanding is thinking that a file link is a shortcut, so let’s check their behavior:

一个常见的误解是认为文件链接是一个快捷方式,所以让我们检查一下它们的行为。

  • A shortcut is a regular file that references a target file
  • Soft/Symbolic link is a file pointer that behaves as the file that is linking to – if the target file gets deleted then the link is unusable
  • A hard link is a file pointer that mirrors the file that it’s linking to, so it’s basically like a clone. If the target file gets deleted, the link file is still valid

Most operating systems (Linux, Windows, Mac) already support soft/hard file links, so it shouldn’t be a problem to work over them using the NIO API.

大多数操作系统(Linux、Windows、Mac)已经支持软/硬文件链接,因此使用NIO API在它们上面工作应该不成问题。

3. Creating Links

3.创建链接

First, we have to create a target file to link to, so let’s sequence some data into a file:

首先,我们必须创建一个目标文件来链接,所以让我们把一些数据排序到一个文件中。

public Path createTextFile() throws IOException {		
    byte[] content = IntStream.range(0, 10000)
      .mapToObj(i -> i + System.lineSeparator())
      .reduce("", String::concat)
      .getBytes(StandardCharsets.UTF_8);
    Path filePath = Paths.get("", "target_link.txt");
    Files.write(filePath, content, CREATE, TRUNCATE_EXISTING);
    return filePath;		
}

Let’s create a symbolic link to an existing file, ensuring that the created file is a symbolic link:

让我们为一个现有文件创建一个符号链接,确保创建的文件是一个符号链接。

public void createSymbolicLink() throws IOException {
    Path target = createTextFile();
    Path link = Paths.get(".","symbolic_link.txt");
    if (Files.exists(link)) {
        Files.delete(link);
    }
    Files.createSymbolicLink(link, target);
}

Next, let’s take a look at a hard link creation:

接下来,让我们看一下硬链接的创建。

public void createHardLink() throws IOException {
    Path target = createTextFile();
    Path link = Paths.get(".", "hard_link.txt");
    if (Files.exists(link)) {
        Files.delete(link);
    }
    Files.createLink(link, target);
}

By listing the files with their differences, we can see that the soft/symbolic link file size is small, while the hard link is using the same space as the linked file:

通过列出文件的差异,我们可以看到,软/符号链接的文件尺寸很小,而硬链接使用的空间与被链接文件相同。

 48K	target_link.txt
 48K	hard_link.txt
4.0K	symbolic_link.txt

To clearly understand what are the possible exceptions that can be thrown, let’s see the checked exceptions on the operations:

为了清楚地了解哪些是可能被抛出的异常,让我们看看操作上的检查异常。

  • UnsupportedOperationException – when the JVM doesn’t support file links in a specific system
  • FileAlreadyExistsException – when the link file already exists, the override is not supported by default
  • IOException – when an IO error occurs, e.g. invalid file path
  • SecurityException – when the link file can’t be created or the target file can’t be accessed because of limited file permissions

4. Operations With Links

4.带链接的操作

Now, if we have a given file system with existing file links, it’s possible to identify them and show their target files:

现在,如果我们有一个给定的文件系统,有现有的文件链接,就有可能识别它们并显示它们的目标文件。

public void printLinkFiles(Path path) throws IOException {
    try (DirectoryStream<Path> stream = Files.newDirectoryStream(path)) {
        for (Path file : stream) {
            if (Files.isDirectory(file)) {
                printLinkFiles(file);
            } else if (Files.isSymbolicLink(file)) {
                System.out.format("File link '%s' with target '%s' %n", 
                  file, Files.readSymbolicLink(file));
            }
        }
    }
}

If we execute it in our current path:

如果我们在当前路径中执行它。

printLinkFiles(Paths.get("."));

We would get the output:

我们会得到输出。

File link 'symbolic_link.txt' with target 'target_link.txt'

Note that hard link files aren’t simply identifiable with NIO’s APIlow-level operations are required to work over that kind of files.

注意,硬链接文件并不能简单地用NIO的API来识别低级别的操作需要在那种文件上工作。

5. Conclusion

5.结论

This article describes the different type of file links, their difference with shortcuts, and how to create and operate over them using a pure Java API that works over the mainstream file systems on the market.

本文介绍了不同类型的文件链接,它们与快捷方式的区别,以及如何使用纯Java API创建和操作它们,并在市场上的主流文件系统上工作。

The implementation of these examples and code snippets can be found over on GitHub.

这些例子和代码片断的实现可以在GitHub上找到over