1. Обзор
В этом уроке мы рассмотрим различные способы создания символической ссылки в Java с помощью NIO.2 API и изучить различия между жесткими и мягкими ссылками на файлы.
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 (DirectoryStreamstream = 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. Заключение
В этой статье описываются различные типы ссылок на файлы, их отличие от ярлыков, а также способы их создания и работы с ними с помощью чистого API Java, который работает над основными файловыми системами на рынке.
Реализацию этих примеров и фрагментов кода можно найти на GitHub .