Criar um link simbólico com Java
1. Visão geral
Neste tutorial, vamos explorar diferentes maneiras de criar um link simbólico em Java usandoNIO.2 API, e explorar as diferenças entre links de arquivos físicos e virtuais.
2. Links duros vs suaves / simbólicos
Primeiro, vamos definir o que são links de arquivo e qual é o comportamento esperado. A file link is a pointer that transparently references a file stored in the file system.
Um mal-entendido comum é pensar que um link de arquivo é um atalho, então vamos verificar seu comportamento:
-
Um atalho é um arquivo regular que faz referência a um arquivo de destino
-
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
-
Um hard link é um ponteiro de arquivo que espelha o arquivo ao qual está vinculado, então é basicamente como um clone. Se o arquivo de destino for excluído, o arquivo de link ainda será válido
A maioria dos sistemas operacionais (Linux, Windows, Mac) já oferece suporte a links de arquivos virtuais / físicos, então não deve ser um problema trabalhar neles usandoNIO API.
3. Criando Links
Primeiro, temos que criar um arquivo de destino para vincular, então vamos sequenciar alguns dados em um arquivo:
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;
}
Vamos criar um link simbólico para um arquivo existente, garantindo que o arquivo criado seja um link simbólico:
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);
}
A seguir, vamos dar uma olhada na criação de um hard link:
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);
}
Ao listar os arquivos com suas diferenças, podemos ver que o tamanho do arquivo de link simbólico / flexível é pequeno, enquanto o link físico está usando o mesmo espaço que o arquivo vinculado:
48K target_link.txt
48K hard_link.txt
4.0K symbolic_link.txt
Para entender claramente quais são as possíveis exceções que podem ser lançadas, vamos ver as exceções verificadas nas operações:
-
UnsupportedOperationException - quando a JVM não suporta links de arquivo em um sistema específico
-
FileAlreadyExistsException - quando o arquivo de link já existe, a substituição não é suportada por padrão
-
IOException - quando ocorre um erro IO, por exemplo caminho de arquivo inválido
-
SecurityException - quando o arquivo de link não pode ser criado ou o arquivo de destino não pode ser acessado devido a permissões de arquivo limitadas
4. Operações com Links
Agora, se temos um determinado sistema de arquivos com links de arquivos existentes, é possível identificá-los e mostrar seus arquivos de destino:
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 o executarmos em nosso caminho atual:
printLinkFiles(Paths.get("."));
Obteríamos a saída:
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 são necessários para trabalhar com esse tipo de arquivo.
5. Conclusão
Este artigo descreve os diferentes tipos de links de arquivos, sua diferença com os atalhos e como criar e operar sobre eles usando uma API Java pura que funciona nos sistemas de arquivos principais do mercado.
A implementação desses exemplos e trechos de código pode ser encontradaover on GitHub.