ファイルパスの正規化

パソコンをつかっていると「ファイル」という概念にでくわす。避けてとおることはできない。そしてプログラマーならばファイルを掌を指すようにつかえなければならない。

しかしこのファイル、いろいろな側面があってとにかく扱いが面倒。タイトルにかかげた「ファイルパス」の「正規化」もそのひとつ。

* * *

ファイルには名前がある。現代的な OS では「ファイルシステム」という管理構造で整理している。ハードディスクドライブや USB スティックメモリー、 CD-ROM や DVD ディスクなど、情報を記録できる媒体に情報を書き、また読みとるための約束ごと。この約束にファイルシステムという名前がついている。

そう。ファイルには名前がある。
そしてファイルにはパスがある。パス。

ファイルはフォルダーにしまわれる。そしてフォルダーもフォルダーにしまうことができる。ファイルがどのフォルダーに入っているのか? これを唯一の間違わない形でたどれるように表現したのが「ファイルパス」。

Windows PC では C:\Users\Taro.Yamada\Documents\MY-TOP-SECRET.txt、 macOS や Linux では /home/taro/my-top-secret.txt などと示されるあれ、である。「\」や「/」で区切られたそれぞれが「フォルダー」の名前で、末尾がファイルの名前。

最上位(ディスクドライブのてっぺん)からみて、どのフォルダーの中のいずれのフォルダーの、そのまた中のフォルダーの、どのファイルか? このたどりかたゆえにパス(道)と呼んでいる。

* * *

さて。

最上位から順にたどることもできるのだけれど、いま操作しているファイルからみてファイルシステムをたどることもできる。「相対パス」と呼ばれる方法である。

ファイルがいまあるフォルダーを「.」であらわす。

./my-top-secret.txt

というかんじに。これはいま見ているフォルダーにある my-top-secret.txt を特定する表記。
ドットをふたつ「..」とつなげるとひとつ上のフォルダーを指せる。

../father's-top-secret.txt

いま見ているフォルダーのひとつ上にある father's-top-secret.txt を指す。

* * *

つまりファイルパスには、最上位階層からフォルダーの名前をつないで特定する「絶対パス」指定と、いまの位置を基準にして親フォルダーにもどったり隣のフォルダーを指したりして特定する「相対パス」指定とがある。

言いかえると、おなじファイルを指すための方法が無数に存在する。(../usr/../usr/he/../../usr/her/../../usr/me みたいにして ../usr/me を指せる。いくらでも相対指定を連ねられる)

この「パス」とあの「パス」はおなじパスか? これはなかなか深い──いや面倒な話で、プログラマーはたびたび頭を悩ませることになる。そうでなくても Windows とその他 OS とではパスセパレーター、「\」と「/」の違いがあるので扱いがややこしい。

加えて Windows の歴史。
MS-DOS から Windows への切り替わり時期に、ファイルに(長い)別名がつけられるようになった。(逆に「隠れた」短い名前があるというほうが現在の事情をよく表す)(ショートファイル名とロングファイル名という)
パスの最大長が 260 文字までというかつての制限をとっぱらうために UNC という表記も導入された。
「絶対パス」指定でさえ複数の表示が可能になっている。(基地外沙汰!)

* * *

そんなわけで賢明なプログラマー諸氏におかれては、ゆめゆめ自分でパスの正規化を実装するなかれ。

API をつかえ。

Windows
PathAllocCanonicalize function (pathcch.h) - Win32 apps | Microsoft Docs

Linux
canonicalize_file_name(3) - Linux manual page (man7.org)

* * *

ここではファイル「パス」に限って話をしたけれど、ファイルには実体の共有という面倒な話がある。シンボリックリンクやジャンクション、ハードリンクと呼ばれるものである。
これはファイルデータそのものに別の名前をつけて管理する方法。

正規化したパスがちがってもファイルはおなじ、ということがありうる。

歴史の重みをかんじる。重い。
気持ちは風車(ドラゴン)を前にしたドン・キホーテ。
討ち死には、したくないなあ。

この記事が気に入ったらサポートをしてみませんか?