1. Panoramica
In questo tutorial, esploreremo diversi modi per creare un collegamento simbolico in Java utilizzando l'API NIO.2 ed esploreremo le differenze tra collegamenti a file hard e soft.
2. Collegamenti hard vs soft / simbolici
Per prima cosa, definiamo cosa sono i collegamenti ai file e qual è il loro comportamento previsto. Un collegamento a un file è un puntatore che fa riferimento in modo trasparente a un file memorizzato nel file system .
Un malinteso comune è pensare che un collegamento a un file sia una scorciatoia, quindi controlliamo il loro comportamento:
- Un collegamento è un file normale che fa riferimento a un file di destinazione
- Il collegamento soft / simbolico è un puntatore a file che si comporta come il file a cui si sta collegando: se il file di destinazione viene eliminato, il collegamento è inutilizzabile
- Un collegamento fisico è un puntatore di file che rispecchia il file a cui si collega, quindi è fondamentalmente come un clone. Se il file di destinazione viene eliminato, il file di collegamento è ancora valido
La maggior parte dei sistemi operativi (Linux, Windows, Mac) supporta già collegamenti a file soft / hard, quindi non dovrebbe essere un problema lavorarci sopra utilizzando l'API NIO.
3. Creazione di collegamenti
Per prima cosa, dobbiamo creare un file di destinazione a cui collegarci, quindi sequenziamo alcuni dati in un 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; }
Creiamo un collegamento simbolico a un file esistente, assicurandoci che il file creato sia un collegamento simbolico:
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); }
Successivamente, diamo un'occhiata alla creazione di un collegamento fisico:
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); }
Elencando i file con le loro differenze, possiamo vedere che la dimensione del file del collegamento soft / simbolico è piccola, mentre l'hard link utilizza lo stesso spazio del file collegato:
48K target_link.txt 48K hard_link.txt 4.0K symbolic_link.txt
Per capire chiaramente quali sono le possibili eccezioni che possono essere lanciate, vediamo le eccezioni verificate sulle operazioni:
- UnsupportedOperationException : quando JVM non supporta i collegamenti ai file in un sistema specifico
- FileAlreadyExistsException : quando il file di collegamento esiste già, l'override non è supportato per impostazione predefinita
- IOException - quando si verifica un errore di I / O, ad es. Percorso file non valido
- SecurityException : quando non è possibile creare il file di collegamento o non è possibile accedere al file di destinazione a causa di autorizzazioni limitate del file
4. Operazioni con collegamenti
Ora, se abbiamo un determinato file system con collegamenti ai file esistenti, è possibile identificarli e mostrare i loro file di destinazione:
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)); } } } }
Se lo eseguiamo nel nostro percorso corrente:
printLinkFiles(Paths.get("."));
Otterremmo l'output:
File link 'symbolic_link.txt' with target 'target_link.txt'
Nota che i file hard link non sono semplicemente identificabili con l'API di NIO , sono necessarie operazioni di basso livello per lavorare su quel tipo di file.
5. conclusione
Questo articolo descrive i diversi tipi di collegamenti ai file, la loro differenza con i collegamenti e come crearli e utilizzarli utilizzando un'API Java pura che funziona sui file system tradizionali sul mercato.
L'implementazione di questi esempi e frammenti di codice può essere trovata su GitHub.