argius note

プログラミング関連

NIO2とWin7とシンボリックリンク

2011-09-18にJava SE 7 (4) - "NIO.2" ファイルシステム関連APIの増強のエントリ中、Files.createSymbolicLinkの箇所で、

WindowsXPではシンボリックリンクはUnsupportedOperationExceptionがthrowされます。(いい加減サポートされてくれないでしょうか。)

と書きました。
このエントリにコメントをいただきまして、Vistaではシンボリックリンクが使えるとのこと。
サポートされてくれてるんじゃん...


XPしか無いからと放っておいたんでしょうか。でも、そういえばWindows7がありました。Vistaでできるようになったってことは、当然Win7でも...どうなんでしょう?


結論から申し上げますと、Win7でもシンボリックリンクが使えます。そして、Files.createSymbolicLinkも使えます!

import java.nio.file.*;

final class SymLink {
    public static void main(String... args) throws Exception {
        Files.createSymbolicLink(Paths.get("argius"),
                                 Paths.get("D:/argius"));
        Files.createSymbolicLink(Paths.get("xxx.java"),
                                 Paths.get("symlinktest.java"));
    }
}

をコンパイルして実行します。createSymbolicLinkメソッドはUnixのlnと引数が逆で、リンクの側が第1引数となります。
実行してみると、

Exception in thread "main" java.nio.file.FileSystemException: argius: クライアントは要求された特権を保有していません。
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:86)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
at sun.nio.fs.WindowsFileSystemProvider.createSymbolicLink(WindowsFileSystemProvider.java:593)
at java.nio.file.Files.createSymbolicLink(Files.java:988)
at SymLink.main(symlinktest.java:6)

エラーになってしまいました。特権が要るみたいです。


コマンドプロンプトを管理者モードで起動して、再度トライ。今度はエラーなしで終了しました。
dirしてみると、

D:\tmp>dir
 ドライブ D のボリューム ラベルは ボリューム です
 ボリューム シリアル番号は xxxx-xxxx です

 D:\tmp のディレクトリ

2011/10/20  20:38    <DIR>          .
2011/10/20  20:38    <DIR>          ..
2011/10/20  20:38    <SYMLINKD>     argius [D:\argius]
2011/10/20  20:38               697 SymLink.class
2011/10/20  20:37               228 symlinktest.java
2011/10/20  20:36    <SYMLINK>      xxx.java [D:\tmp\symlinktest.java]
               3 個のファイル                 925 バイト
               3 個のディレクトリ     xxx,xxx,xxx バイトの空き領域

D:\tmp>

となります。


なお、Windowsでのリンクを作るコマンドはmklinkです。mklinkはcreateSymbolicLinkと同じくUnixのlnと引数が逆です。
Cygwin(1.7以降?)では、シンボリックリンクとして見えます。