1概要

このチュートリアルでは、https://www.baeldung.com/java-nio-2-file-api[NIO.2 API]を使用してJavaでシンボリックリンクを作成するさまざまな方法を探り、その違いを探ります。ハードファイルリンクとソフトファイルリンク。

まず、ファイルリンクとは何か、またそれらの期待される動作を定義しましょう。 ** ファイルリンクは、ファイルシステムに格納されているファイルを透過的に参照するポインタです。

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

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

  • ソフト/シンボリックリンクは、ファイルとして動作するファイルポインタです。

リンク先 – ターゲットファイルが削除された場合、リンクは使用できません
** ハードリンクは、リンク先のファイルを反映したファイルポインタです。

そう、それは基本的にクローンのようなものです。ターゲットファイルが削除されても、リンクファイルはまだ有効です。

ほとんどのオペレーティングシステム(Linux、Windows、Mac)はすでにソフト/ハードファイルリンクをサポートしているので、https://docs.oracle.com/javase/tutorial/essential/io/を使用してそれらを操作することは問題になりません。 links.html[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<Path> 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'

  • ハードリンクファイルは

    NIOのAPI

    ** で簡単に識別できるわけではないので注意してください。その種類のファイル。


5結論

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

これらの例とコードスニペットの実装はhttps://github.com/eugenp/tutorials/tree/master/core-java-io[GitHubで動く]にあります。