LoginSignup
10
16

More than 1 year has passed since last update.

Windowsのハードリンクとジャンクションとシンボリックリンクについて

Last updated at Posted at 2021-10-28

WindowsのNTFSファイルシステムで、サポートされているファイルリンクとして、ハードリンクとジャンクションとシンボリックリンクがあります。

それぞれについての理解をまとめます。

ドキュメント

マイクロソフトのドキュメント

ハードリンク

ハードリンクは同一ボリューム内の1つのファイルに対して、複数のパスを作ることができます。
ファイルに対して作成するものとなり、ディレクトリに対してハードリンクを作成する事はできません。

複数パスを作ることにより、作成したすべてのファイルパスが削除されるまで削除されず、ハードリンクが一つでも残されていれば引き続きアクセスする事ができます。

例としてはc:/temp/file/dir-origin/file-origin.txt というオリジナルのファイルに対して、ハードリンクC:\temp\file\hardlink.txtを作成して確認してみます。

Hardlinkサンプル
# c:\temp\file\dir-origin を作成
# file-origin.txtを作成
New-Item -ItemType File -Path C:\temp\file\dir-origin\file-origin.txt -Value HelloWorld -Force

# hardlinkを作成
New-Item -ItemType HardLink -Path C:\temp\file\hardlink.txt -Target C:\temp\file\dir-origin/file-origin.txt

作成したhardlink.txt側をテキストエディタで開いて変更後、origin.txt側を開くとhardlink.txt実施した変更が反映される事を確認できます。

fsutil file queryfileid <<ファイルパス>>で実際に格納されている場所File IDが取得できるようなので確認してみます。

PowerShell:fsutilでハードリンクのFile IDを確認
fsutil file queryfileid C:\temp\file\dir-origin\file-origin.txt
fsutil file queryfileid C:\temp\file\hardlink.txt

image.png

file-origin.txthardlink.txtFile IDが同じ値である事を確認できます。

ジャンクション

ジャンクション(ソフトリンク)は同一のコンピュータ上のディレクトリに対して、リンクを作成する機能となり。
ハードリンクとは異なり、ディレクトリのみを対象として作成する事ができます。

あくまでリンクとなるため参照先となるファイルが削除される、ディレクトリ名が変更されると作成したジャンクションからリンク先へアクセスする事はできなくなります。

また参照先の指定については絶対パスのみ利用する事ができます。

# ジャンクションの作成
New-Item -ItemType Junction -Path C:\temp\file\junction -Target C:\temp\file\dir-origin

C:\temp\file\junctionにアクセスすると、file-origin.txtが存在して先程作成した、c:\temp\file\dir-originにリンクされている事がわかるかと思います。

fsutilでジャンクションのFileIDを確認
fsutil file queryfileid C:\temp\file\dir-origin
fsutil file queryfileid C:\temp\file\junction

下記画像のようにすべてのFile IDが別物となっており、ハードリンクとは違う事がわかります。

image.png

シンボリックリンク

シンボリックリンクは、ハードリンク、ジャンクションとは異なりファイル、ディレクトリ問わずにリンクを作成する事ができます。
基本的には、作成に管理者権限が必要となります。

またジャンクションとは異なり、参照先を絶対パスだけではなく相対パスでも記述する事ができます。

【管理者権限が必要】
# 絶対パスでシンボリックリンクを作成
New-Item -ItemType SymbolicLink -Path C:\temp\file\symbolic-absolute-dir -Target C:\temp\file\dir-origin
New-Item -ItemType SymbolicLink -Path C:\temp\file\symbolic-absolute-file.txt -Target C:\temp\file\dir-origin\file-origin.txt

# 相対パスでシンボリックリンクを作成
New-Item -ItemType SymbolicLink -Path C:\temp\file\symbolic-relative-dir -Target .\dir-origin
New-Item -ItemType SymbolicLink -Path C:\temp\file\symbolic-relative-file.txt -Target ./dir-origin/file-origin.txt
fsutilでシンボリックリンクのFileIDを確認
fsutil file queryfileid C:\temp\file\dir-origin
fsutil file queryfileid C:\temp\file\dir-origin\file-origin.txt

fsutil file queryfileid C:\temp\file\symbolic-absolute-dir
fsutil file queryfileid C:\temp\file\symbolic-absolute-file.txt

fsutil file queryfileid C:\temp\file\symbolic-relative-dir
fsutil file queryfileid C:\temp\file\symbolic-relative-file.txt

下記画像のようにすべてのFile IDが別物となっており、ハードリンクとは違う事がわかります。

image.png

おまけ fsutil usnを確認してみる

fsutil-usn-readdata
fsutil usn readdata c:\temp\file\dir-origin | findstr ^FileRef#
fsutil usn readdata c:\temp\file\dir-origin\file-origin.txt | findstr ^FileRef#

fsutil usn readdata c:\temp\file\junction | findstr ^FileRef#
fsutil usn readdata c:\temp\file\hardlink.txt | findstr ^FileRef#

fsutil usn readdata c:\temp\file\symbolic-absolute-dir | findstr ^FileRef#
fsutil usn readdata c:\temp\file\symbolic-absolute-file.txt | findstr ^FileRef#

fsutil usn readdata c:\temp\file\symbolic-relative-dir | findstr ^FileRef#
fsutil usn readdata c:\temp\file\symbolic-relative-file.txt | findstr ^FileRef#

image.png

Name FileRef
dir-origin FileRef# : 0x00000000000000000029000000036159
dir-origin\file-origin.txt FileRef# : 0x0000000000000000001a000000037837
junction FileRef# : 0x00000000000000000029000000036159
hardlink.txt FileRef# : 0x0000000000000000001a000000037837
symbolic-absolute-dir FileRef# : 0x00000000000000000029000000036159
symbolic-absolute-file.txt FileRef# : 0x0000000000000000001a000000037837
symbolic-relative-dir FileRef# : 0x00000000000000000029000000036159
symbolic-relative-file.txt FileRef# : 0x0000000000000000001a000000037837

各ファイルについて確認してみる

Get-ChildItemで取得できる構造のLinkTypeを参照すると、ハードリンクなのかジャンクションなのかシンボリックリンクなのか判別する事ができます。

Get-ChildItem -Recurse  | Select-Object fullname , LinkType | sort FullName

image.png

総評

ジャンクションとハードリンク。 シンボリックリンク については実際に作成してみて確認するのがわかりやすいのでおすすめ。

10
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
16