Créer un lien symbolique avec Java

1. Vue d'ensemble

Dans ce didacticiel, nous allons explorer différentes manières de créer un lien symbolique en Java à l'aide desNIO.2 API, et explorer les différences entre les liens de fichiers matériels et logiciels.

Tout d'abord, définissons ce que sont les liens de fichiers et quel est leur comportement attendu. A file link is a pointer that transparently references a file stored in the file system.

Un malentendu courant est de penser qu’un lien vers un fichier est un raccourci, alors vérifions leur comportement:

  • Un raccourci est un fichier standard qui référence un fichier cible.

  • 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

  • Un lien physique est un pointeur de fichier qui reflète le fichier auquel il est lié, c'est donc essentiellement comme un clone. Si le fichier cible est supprimé, le fichier de lien est toujours valide.

La plupart des systèmes d’exploitation (Linux, Windows, Mac) prennent déjà en charge les liens de fichiers logiciels / matériels, il ne devrait donc pas être un problème de travailler dessus en utilisant lesNIO API.

Tout d'abord, nous devons créer un fichier cible vers lequel établir un lien, donc séquençons certaines données dans un fichier:

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

Créons un lien symbolique vers un fichier existant, en nous assurant que le fichier créé est un lien symbolique:

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

Jetons ensuite un coup d'œil à la création d'un lien physique:

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

En répertoriant les fichiers avec leurs différences, nous pouvons constater que la taille du fichier de lien symbolique / symbolique est petite, alors que le lien physique utilise le même espace que le fichier lié:

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

Pour comprendre clairement quelles sont les exceptions possibles qui peuvent être levées, voyons les exceptions vérifiées sur les opérations:

  • UnsupportedOperationException - lorsque la machine virtuelle Java ne prend pas en charge les liens de fichiers dans un système spécifique

  • FileAlreadyExistsException - lorsque le fichier de lien existe déjà, le remplacement n'est pas pris en charge par défaut

  • IOException - lorsqu'une erreur IO se produit, par ex. chemin de fichier invalide

  • SecurityException - lorsque le fichier de lien ne peut pas être créé ou que le fichier cible n'est pas accessible en raison des autorisations de fichier limitées

Désormais, si nous avons un système de fichiers donné avec des liens de fichiers existants, il est possible de les identifier et d'afficher leurs fichiers cibles:

public void printLinkFiles(Path path) throws IOException {
    try (DirectoryStream 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));
            }
        }
    }
}

Si nous l'exécutons dans notre chemin actuel:

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

Nous aurions la sortie:

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

Note that hard link files aren’t simply identifiable with NIO’s API,low-level operations sont nécessaires pour travailler sur ce type de fichiers.

5. Conclusion

Cet article décrit les différents types de liens de fichier, leur différence avec les raccourcis, et comment les créer et les utiliser à l'aide d'une API Java pure fonctionnant sur les systèmes de fichiers classiques du marché.

L'implémentation de ces exemples et extraits de code peut être trouvéeover on GitHub.