Windowsにおけるディレクトリ、フォルダ、パスの使い分けー絶対パスと相対パスとセグメントまでの整理2/2

[Windowsにおけるディレクトリ、フォルダ、パスの使い分けー絶対パスと相対パスとセグメント文字までの整理1/2](https://qiita.com/Q11Q/items/8f414689f7b4a763d3f6)の続きです
#絶対パス、相対パス、セグメント文字、ディレクトリ区切り文字
今回扱うのはこの4つになる。

##Windowsにおける絶対パスと相対パスは明確な定義がある

>###[Windows システムのファイル パス形式](https://docs.microsoft.com/ja-jp/dotnet/standard/io/file-path-formats)
2019/06/06
System.IO 名前空間の型の多くのメンバーには path パラメーターが含まれています。このパラメーターによって、ファイル システム リソースの絶対パスまたは相対パスを指定できます。 このパスはその後、Windows ファイル システム API に渡されます。 このトピックでは、Windows システムで利用できるファイル パスの形式について説明します。
####従来の DOS パス
標準 DOS パスは 3 つの要素で構成できます。
<UL><li>ボリュームまたはドライブ文字とそれに続くボリューム区切り記号 (:)。
<li>ディレクトリ名。 ディレクトリ区切り文字によって、入れ子になっているディレクトリ階層内でサブディレクトリが分割されます。
<li>任意のファイル名。 ディレクトリ区切り文字によって、ファイル パスとファイル名が分割されます。
</UL>
<b>3 つのコンポーネントがすべて存在する場合、パスは絶対パスになります。 </B>ボリュームまたはドライブ文字が指定されておらず、ディレクトリ名がディレクトリ区切り文字で始まる場合、パスは現在のドライブのルートからの相対パスとなります。 それ以外の場合、パスは現在のディレクトリに相対となります。 次の表では、想定されるディレクトリとファイル パスをいくつかまとめています。

>|パス 	|説明|
|:------|:----|
|`C:\Documents\Newsletters\Summer2018.pdf` 	|ドライブ C: のルートからの絶対ファイル パス。|
|`\Program Files\Custom Utilities\StringFinder.exe` 	|現在のドライブのルートからの絶対パス。|
|`2018\January.xlsx` 	|現在のディレクトリのサブディレクトリにあるファイルへの相対パス。|
|`..\Publications\TravelBrochure.pdf` 	|現在のディレクトリと同等になるディレクトリにあるファイルへの相対パス。|
|`C:\Projects\apilibrary\apilibrary.sln` 	|ドライブ C: のルートからのファイルへの絶対パス。|
|`C:Projects\apilibrary\apilibrary.sln` 	| C: ドライブの現在のディレクトリからの相対パス。|

>####重要
`最後の 2 つのパスの違いにご注意ください。 いずれも任意のボリューム指定子を指定しますが (いずれの場合も C:)、最後から 2 番目のパスが指定ボリュームのルートから始まるのに対し、最後のパスは指定ボリュームのルートから始まりません。 結果として、最後から 2 番目のパスがドライブ C: のルート ディレクトリからの絶対パスであるのに対し、最後のパスはドライブ C: の現在のディレクトリからの相対パスになります。 最後から 2 番目のパス形式を意図しているときに最後のパス形式を使用することが、Windows ファイル パス関連のバグの共通の源になっています。`

>IsPathFullyQualified メソッドを呼び出すことで、ファイルが完全修飾であるかどうかを判断できます。完全修飾の場合、パスが現在のディレクトリに依存せず、現在のディレクトリが変更されても完全修飾のパスは変わりません。 そのようなパスには相対ディレクトリのセグメント (. や ..) が含まれている可能性があり、解決後のパスが常に同じ場所を指す場合、完全修飾できることにご留意ください。

サーバーは別（ただしサーバーもドライブを割り当てるとおなじになる）だが、一般的に相対パスは「カレントディレクトリからファイルやフォルダを示したもの」といわれるし、実際上記もそうなっている。
しかし重要なのは、Windowsにおいては***3つの条件を満たしてファイルまで表示しているのが絶対パス***という原則が存在していることだ。
さらに、ファイルまでのパスをファイルパス、ディレクトリだけの場合をディレクトリパス、フォルダーパスなどと表現される。この分類だと、絶対パスとは原則としてファイルパスしかありえないということになる。

###Microsoftの解説以外を読むほど混乱する
https://ja.wikipedia.org/wiki/%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA
>ディレクトリ (英: directory) は、コンピュータのファイルシステムにおいて、ファイルをグループ化するための特殊なファイル[1]で、整理・管理などの目的で活用される。ディレクトリの中にも、通常のファイルだけでなく入れ子的にディレクトリを作って、任意の階層を持たせて管理できることがほとんどである。

>ファイルの入れ物（容器）などとも表現され、GUIでは文具のフォルダーのようなメタファーで表現されることが多い。ただし、物理的な容器であるのはHDDなどのメディアそのものであるので、ディレクトリは「ファイルへの見出し[2]の入れ物」と表現する方が正確である。 

[パスの考え方(PATH)  http://hp.vector.co.jp/authors/VA029438/msdos/ms_dos_path.html](http://hp.vector.co.jp/authors/VA029438/msdos/ms_dos_path.html])
>パス、パスを通す
　「実行パス(を通す)」の話は前ページ の説明ですみましたが、ここでの、「パスを通す」の「パス」は、実行パスに限らないことに注意してください。
※注目 : 「～にパスを通す」 が分かりにくい場合は、「～をなんとかパスとして有効にする」 と読み替えると遥かに分かりやすいです。 なんとかパス、の部分は、実行パス（環境変数のPath）であったり、インクルードパスであったり、ライブラリパスであったりします。
　パス、とディレクトリ (ファイルも) は、ほぼ同じような意味あいです。パスとはファイルやディレクトリを指定するための「表記」だと思えばいいと思います。
 パス、は、ディレクトリ名をのこともあれば、ファイル名のこともあります。

編注：インクルードパスやライブラリパスはC言語で出てくる (https://teratail.com/questions/197288)
[［パスとディレクトリ］（C++）](http://docwiki.embarcadero.com/RADStudio/Rio/ja/%EF%BC%BB%E3%83%91%E3%82%B9%E3%81%A8%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%EF%BC%BD%EF%BC%88C%2B%2B%EF%BC%89)
ここでリンカーパスなどの説明を見ることができるが、PCが参照するときがPathでなにかを出力するときがディレクトリに分かれている。

[コマンドラインくらい使っとけ ~Windowsに愛の手を~2001.10](http://pctraining.s21.xrea.com/text/cui-win.html)
> ご存知の通り、ディスクは階層構造になっています。ルートディレクトリと呼ばれる、ドライブの直下のディレクトリから始まって、その下の階層のサブディレクトリと、ディレクトリの中のファイルの集合体となっています。

>カレントディレクトリというのは Explorer で言うと、いま開いているフォルダのことです。 

[§２　ファイルの処理　VB6 http://masudahp.web.fc2.com/vb6/vb6first/fileinout01.html](http://masudahp.web.fc2.com/vb6/vb6first/fileinout01.html)
>　ファイルは整理のためにフォルダ（ディレクトリ）*1に分類して保存するのが一般的である。「どのドライブ」の「どのフォルダ」に記憶されているかを表す名前をパス名という。パス名は指定方法によって絶対パスと相対パスがある。ディスクには一番元になるルートディレクトリというものがあり、ルートディレクトリの中にファイルやフォルダが記憶されている。
　絶対パスはルートディレクトリからファイル名やフォルダ名を指定する方法である。ルートディレクトリは円マーク(UNIXは/)で表す。相対パスはカレントディレクトリ（現在ファイル操作の対象となっているディレクトリ）からファイル名やフォルダ名を指定する方法である。フォルダ名とファイル名は円マーク(UNIXは/)でつなぐ。

いくつかのサイトの表記をみると、実は微妙にニュアンスが違うことがわかると思う。これが絶対パスと相対パスをわかりづらくしている原因だと言える。

####Windowsにおける絶対パスをおさえるといいかもしれない
Windowsにおける絶対パスとはファイルの位置をドライブから階層を示して表示したファイルパスである。というのが基本で、これをふまえて相対パスを見たほうがよい。試験のテクニックではないが、3つの条件が揃っている以外が相対パスなので、そういう整理をする。多言語で異なる場合にはまず絶対パスから比較する。サーバーの場合もドライブ文字を割り当てると使える。

####ディレクトリとパスの用語の使い分け
当方で検索した結果、一般的にPathというのは経路であるため複数の階層の下にあるディレクトリやファイルにおいて、Windowやアプリが参照するディレクトリやファイルに使われ、ディレクトリは出力ディレクトリなど、出力する先を設定する場合はディレクトリを使う傾向がある。

##セグメント文字とディレクトリ区切り文字
相対パスで使われる半角ピリオドをセグメントという。またディレクトリを区切る文字（セパレーター）をディレクトリ区切り文字といい、日本語環境では円マーク&yen;だが、海外ではバックスラッシュである。しかしここで[Windowsパス名の落とし穴 ](https://www.ipa.go.jp/security/awareness/vendor/programmingv1/b08_01.html)
>次のパス名はすべて同じファイルを示すものとして解釈される:
<OL>
<li>d:&yen;InetPub&yen;wwwroot&yen;secret&yen;data.txt<br>基本形</br>
<li>d:\inetpub\WWWROOT\SECRET\DATA.TXT<br>大文字小文字は同一視される</br>
<li>d:/InetPub/wwwroot/secret/data.txt<br>ディレクトリの区切りに「/」も使える</br>
<li>d:\\InetPub\\\wwwroot\\\\secret\\\\\data.txt<br>ディレクトリの区切り文字は幾つか重複しても構わない</br>
<li>d:////InetPub///wwwroot//secret/data.txt<br>「/」も重複できる</br>
<li>d:\InetPub\.\wwwroot\.\.\secret\.\.\.\data.txt<br>「カレントディレクトリ」を表す . を差し挟むことができる</br>
<li>d:\fake\fake\..\..\InetPub\wwwroot\secret\data.txt<br>実在しないディレクトリもあとで「..」で遡れば指定可能</br>
</OL>

さらに&yen;と/を混在させてもよい
たとえばProgram Filesはスペースが有るため二重引用符で囲むが
コマンドプロンプトにおいて

dir "c:&yen;/program files"

のようにしてもフォルダやファイルが表示される。
最もこれらの表示はIPAの記事にあるように設定でできなくすることはできる。

#####NOTE:円マークの表示
上記の表中、円マークはHTMLの特殊文字の`&yen`に続けてセミコロンを書くことで表示させている
[html上でバックスラッシュと円マークを共存表示する方法 ](https://singoro.net/note/backslash-yen_sign/)

##ピリオドあるいはドットがカレントディレクトリを表すとは限らない
[Windowsのコマンドプロンプトを便利に使うための10のミニテクニック](https://codezine.jp/article/detail/3879)
`Start .` `Start.`
といろいろな使い方がある。特にDIrを使うときが便利である
[Dir関数でサブフォルダを取得する OfficeTanaka](http://officetanaka.net/excel/vba/tips/tips95.htm)
>なお、カレントフォルダはC:\Workにしてあります。
>ところで見慣れないものがあります「.」と「..」とは何でしょう。MS-DOSの時代には必須の知識だったのですが、***「.」は自分自身のフォルダを表し***「..」は1つ上のフォルダを意味しています。カレントフォルダがC:\Workなら、

>「.」 = C:\Work
「..」 = C:\

ここで田中大先生はカレントディレクトリと言わず自身のフォルダと言っている。
これは実は「.」は必ずしもカレントではないためである。正確に言うと、それだとシステム領域を踏んでバグを起こしたり、ショートカットだと作業フォルダを見たりするためである。
また、「カレント」は文脈上でなんのカレントなのか注意した方が良い。システムがカレントなのか、DOSのプロンプトがカレントなのか、アプリケーションがカレントなのか、アプリケーション（スクリプト）の存在するフォルダがカレントなのか、ショートカットの作業フォルダがカレントなのか、カレントディレクトリ（カレントフォルダ）はDOSプロンプト（コマンドプロンプト）でも、アプリケーションでも用いいられるためである。


この場合、田中大先生のサンプル

```vb
Sub Sample()
    Dim buf As String, msg As String
    buf = Dir("tanaka*.*")
    Do While buf <> ""
        msg = msg & buf & vbCrLf
        buf = Dir()
    Loop
    MsgBox msg
End Sub
```

とは
[ChDrive ステートメント](https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/chdrive-statement)
[ChDirステートメント](https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/chdir-statement)
を用いて

```vb
Sub Sample()
    ChDrive "C"
    ChDir = "C:\Work"
    Dim buf As String, msg As String
    buf = Dir("tanaka*.*")
    Do While buf <> ""
        msg = msg & buf & vbCrLf
        buf = Dir()
    Loop
    MsgBox msg
End Sub
```

ということなので、ExcelのVBAにおけるカレントディレクトリということになる。このとき、例えばExplorerのカレントディレクトリは同じではないしDOSプロンプトのカレントが変わるわけでもない。またChDirはやはりディレクトリなのだが、パスと記載している。
[ChDirステートメント](https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/chdir-statement)
>パス引数は必須であり新しい既定のディレクトリまたはフォルダーになるディレクトリまたはフォルダーを識別する文字列式です。 パスにはドライブを含めることができます。 ドライブが指定されていない場合は、ChDirは、現在のドライブで既定のディレクトリまたはフォルダーを変更します。
The required path argument is a string expression that identifies which directory or folder becomes the new default directory or folder. The path may include the drive. If no drive is specified, ChDir changes the default directory or folder on the current drive.

ここは例外を踏まえてDirectory or Folderとしているのだろう。また、相対パスでも記述できるという意味になる。ただしドライブから記述したからと言って、絶対パスとするのはWindowsの定義からは誤りとなる。このためパスにドライブを含むことができるという表現になっている。そして経路のため、パスという表現が出てくる。この記述を読み解くには当記事のように前回からの流れをおさえないと全く意味不明な文章である。

いままでの流れに合わせてChDirの説明を記述するとこうなると思われる。
Chridr path
pathは省略不可の新しい既定のディレクトリを表す文字列です。この文字列にはドライブから絶対パスのように記述することも、現在のカレントディレクトリから相対パスとして記述することもできます。存在しないディレクトリを指定するとエラーになります。相対パスのセグメント文字を使うと一つ上のディレクトリをかんたんに記述できます。Windowsは `ChDir ".."` Power Macintoshは `ChDir "::"`です。異なるドライブのディレクトリを指定すると、カレントディレクトリは変更できますが、既定のドライブは元のドライブのままで変更されません。しかしそのような場合には異なるドライブに変更する場合にはChDirveを用いたうえでChDirを用いて変更するほうが可読性は高いです。



[カレントフォルダ（CurDir 関数、ChDir ステートメント、ChDrive ステートメント）  https://excelwork.info/excel/funccurdir/](https://excelwork.info/excel/funccurdir/)
###~~"."はルートは意味しない場合がある~~

[CScriptでファイル一覧作成 https://qiita.com/nobu-maple/items/20c675f9c8f4db55b4c0](https://qiita.com/nobu-maple/items/20c675f9c8f4db55b4c0)
`FindFolder FSO.GetFolder(".")`
これをC:\CsTest.VBSとおいて
CMD.Exeで
Cd /D D:\
とする
そして
Cscript.Exe //Nologo CSlist.vbs>List.tsv
D:\CSlist.vbs(22, 5) Microsoft VBScript 実行時エラー: 書き込みできません。


スクリプト:
行:22
文字:5
エラー:書き込みできません
コード:800A0046
ソース:Microsoft VBSCript 実行時エラー

これはハードでも外付けSSDドライブでも同じである。つまりルートに置くと不具合が起きてしまう。
またWScipt.Argumentを使ってもエラーになる。
だからといってカレントディレクトリをD:\に設定して
`D:\>Dir .`
だとルートのファイル一覧が出る。このとき
`D:\>Dir ..`
としても同じである。セグメント文字の資料は非常に検索が困難で、資料自体も少ないため、これがバグなのか、仕様なのか不明である。~~しかし、必ずしもカレントディレクトリを意味しない場合がある。~~これはシステム領域を踏んでいるためのようだ。これを踏まえたものを後ほど公開する。

[NYORO PRESS](http://nyoro2.net/wp/?p=268)
>ショートカットの「作業ディレクトリ」の設定に注意

>ところが、スクリプトをショートカットから実行していると、上記コードを使っても、カレントフォルダ以外が返ってくることがあった。

>実験してみたところ、上記コードによって得られるカレントフォルダは、どうやらショートカットのプロパティの「作業フォルダ」の値に依存しているらしい。

```js
var fso = WScript.CreateObject("Scripting.FileSystemObject");
var cwd = fso.GetFolder(".").Path;
```

Jscriptでも取得できる。
fso.GetFolder(".").Pathを省略した形だとわかる。ここでもセグメント文字が使われている。
ただし作業フォルダを設定していると、そこに依存する。

相対パスのセグメント文字**Relative directory segments (`.` and `..`)** はCMD及び、VBAにおいてDirかFilesystemObjectで出現するが、可読性が低い。