Перейти к основному содержимому

Создайте символическую ссылку с помощью Java

· 3 мин. чтения

1. Обзор

В этом руководстве мы рассмотрим различные способы создания символической ссылки в Java с использованием API NIO.2 и рассмотрим различия между жесткими и программными ссылками на файлы.

2. Жесткие и мягкие/символические ссылки

Во-первых, давайте определим, что такое файловые ссылки и каково их ожидаемое поведение. Ссылка на файл — это указатель, который прозрачно ссылается на файл, хранящийся в файловой системе .

Распространенным заблуждением является мнение, что ссылка на файл является ярлыком, поэтому давайте проверим их поведение:

  • Ярлык — это обычный файл, который ссылается на целевой файл.
  • Мягкая/символическая ссылка — это указатель файла, который ведет себя как файл, на который делается ссылка — если целевой файл удаляется, ссылка становится непригодной для использования.
  • Жесткая ссылка — это указатель файла, который отражает файл, на который он ссылается, поэтому он в основном похож на клон. Если целевой файл удаляется, файл ссылки по-прежнему действителен.

Большинство операционных систем (Linux, Windows, Mac) уже поддерживают программные/жесткие ссылки на файлы, поэтому не должно возникнуть проблем с их обработкой с помощью NIO API .

3. Создание ссылок

Во-первых, нам нужно создать целевой файл для ссылки, поэтому давайте упорядочим некоторые данные в файл:

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;
}

Давайте создадим символическую ссылку на существующий файл, убедившись, что созданный файл является символической ссылкой:

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);
}

Далее, давайте взглянем на создание жесткой ссылки:

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);
}

Перечислив файлы с их различиями, мы видим, что размер файла мягкой/символической ссылки небольшой, в то время как жесткая ссылка использует то же пространство, что и связанный файл:

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

Чтобы четко понять, какие возможные исключения могут быть выброшены, давайте посмотрим проверенные исключения для операций:

  • UnsupportedOperationException — когда JVM не поддерживает ссылки на файлы в конкретной системе.
  • FileAlreadyExistsException — когда файл ссылки уже существует, переопределение не поддерживается по умолчанию.
  • IOException — когда возникает ошибка ввода-вывода, например, неверный путь к файлу.
  • SecurityException — когда файл ссылки не может быть создан или к целевому файлу нет доступа из-за ограниченных прав доступа к файлу.

4. Операции со ссылками

Теперь, если у нас есть данная файловая система с существующими файловыми ссылками, их можно идентифицировать и показать их целевые файлы:

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));
}
}
}
}

Если мы выполним его по нашему текущему пути:

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

Мы получили бы вывод:

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

Обратите внимание, что файлы жестких ссылок не просто идентифицируются с помощью API NIO , для работы с такими файлами требуются низкоуровневые операции .

5. Вывод

В этой статье описываются различные типы ссылок на файлы, их отличие от ярлыков, а также способы их создания и работы с ними с помощью чистого Java API, который работает с основными файловыми системами на рынке.

Реализацию этих примеров и фрагментов кода можно найти на GitHub .