Javaとのシンボリックリンクを作成する

1. 概要

このチュートリアルでは、NIO.2 APIを使用してJavaでシンボリックリンクを作成するさまざまな方法を探り、ハードファイルリンクとソフトファイルリンクの違いを探ります。

まず、ファイルリンクとは何か、およびそれらの予想される動作は何かを定義しましょう。 A file link is a pointer that transparently references a file stored in the file system

よくある誤解は、ファイルリンクがショートカットであると考えていることです。そこで、それらの動作を確認しましょう。

  • ショートカットは、ターゲットファイルを参照する通常のファイルです。

  • 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

  • ハードリンクは、リンク先のファイルをミラーリングするファイルポインタであるため、基本的にはクローンのようなものです。 ターゲットファイルが削除されても、リンクファイルは有効です

ほとんどのオペレーティングシステム(Linux、Windows、Mac)は、すでにソフト/ハードファイルリンクをサポートしているため、NIO APIを使用してそれらを処理することは問題ありません。

まず、リンクするターゲットファイルを作成する必要があるので、いくつかのデータをファイルにシーケンスしてみましょう。

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 –IOエラーが発生したとき。 無効なファイルパス

  • SecurityException –ファイルのアクセス許可が制限されているためにリンクファイルを作成できない場合、またはターゲットファイルにアクセスできない場合

これで、既存のファイルリンクを持つ特定のファイルシステムがある場合、それらを識別してターゲットファイルを表示することができます。

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

現在のパスで実行する場合:

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

出力が得られます:

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

Note that hard link files aren’t simply identifiable with NIO’s APIlow-level operationsは、その種類のファイルを処理するために必要です。

5. 結論

この記事では、さまざまなタイプのファイルリンク、ショートカットとの違い、および市場の主流のファイルシステム上で動作する純粋なJava APIを使用してそれらを作成および操作する方法について説明します。

これらの例とコードスニペットの実装はover on GitHubにあります。