MS-Windowsの256バイト問題

 共有フォルダの構成変更とやらがあるそうで、すなおにファイルを移動させようとしてドキ!1つ深いフォルダに移して移行前にどこにあったか分かりやすくすることを考えたのだが、そうなるとファイルのパス長が今までよりも長くなる。確か256バイトという制限があったよなあ。
 WikipediaのNT File Systemの欄を見ると、32,767文字に拡張されたそうだ。ああよかった。

 ところが、作業を始めてみると、エラーメッセージ続出、どうやら長すぎるパス長のものは引っかかるようだ。タイムスタンプが古いものについては、適当な階層で右クリックから[送る(N)]-[圧縮(zip形式)フォルダ]でアーカイブをかけて、パス長を縮めてその場をしのごうとしたが、アーカイブですらエラーメッセージが出るものがある。やっぱり256バイトの制限は生きている?拡張されたというの、Wikipediaにしか載っていないしナア。少々眉唾。
 実験のために意識して、深い階層で長いファイル名のファイルを作ろうとした。ファイル名が入らなくなった。「やはり制限は生きている」。ではなぜ、256バイト超のパス長のファイルが存在しうるか?どうやらコピー/移動の結果長いパス長ができるのはいいらしい。それこそ、今回のようにディレクトリの整理として、古いファイルを例えば案件対応時期ごとにサブフォルダを作って、そこに移動させてゆくことを繰り返すと、いつかは256バイトを超えてしまうことがあるみたいだ。
 ものすごく深読みすると、NTFSの制限は32767文字。MS-Windowsの制限は256バイト、従ってNTFSのみを操作するファイルコピーは256バイトの制限はないが、これをMS-Windowsのユーティリティで扱おうとすると256バイトの制限に引っかかる。すんなり受け取りがたいって?でもHPFS開発チームはMS-Windowsの制限に引きずられるつもりはなかったと思うぞ。(パーティションテーブルのIDがHPFSのものを勝手に上書きした、ということはカトラーがなんと言おうと開発チームはWindowsNT1.0から続く独立したチームだったと考えられる。)

 作業時のエラーメッセージも、256バイト超ファイルをコピーしようとしたとき必ず出るというわけではない。かなりいい加減。でもなんとかしないとな、ということで妙な責任感が湧く。

 よほど長いパス名ならともかく、とにかく移動が出来て、使えるんだったらいいんじゃないかという説があるかもしれないが、気持ちが悪い。プログラマーの経験があれば分かると思うが、バックアップソフトを作る側のことを考えてくれ。バックアップソフトは単なるコピーと違って「どのファイルをバックアップしたか」の一覧をログとして記録し、実行結果として出力するものだ。その際、当然パス名をプログラム内にストアするが、このときのバッファーとして何バイト取る?僕ならMS-Windowsがサポートするといわれている256バイトにする。ということは256バイト以上のパス長を持つファイルはバックアップを取ったという記録が残らないわけだ。するとバックアップから戻せない可能性が出てくる。バックアップが取られていたと思っていたところ、実は・・・、となるとかなり影響がでかい。
 さらに、運用部署が共有フォルダの物理ドライブを変更するときのことを考えてみよう。バックアップから新しいディスクにロードしないか?すると長いパス長のファイルは移行されず、消える。
 確かに想像だ。あとから知った話だがバージョンアップのときに512バイトに拡張したバックアップソフトもあるらしい。が、その辺を調べても分からなかった以上、直せるものは直しておこう、と考えるのが賢明というものである。

 パス長を求めるフリーソフトを探したがない。kurdamnが闇に葬られて以来プログラム作成環境は廃棄しているので、仕方ない、手に入るものを組み合わせよう。
 まずファイルリストを取得しなければならない、ので「ファイルリスト作成機」を落としてくる。これでパス名、ファイル名、セキュリティの所有者、最終更新日時をそろえる。なぜセキュリティの所有者を見るか?「なんとかして」という先を探すため。なぜ最終更新日時をとるか?「こんな古いのいらないよね」と言うため。

 で、パス名とファイル名の長さを足して256を超えるものを出力するawkのスクリプトを書く。

BEGIN{FS="\t"
     OFS="\t"}
{
if(length($1)+length($2) > 255){print($0)}
}
あー単純。

 さて、こいつらをどうするか。消してよいものは消す。よく分からないものは適当な階層でアーカイブをかけて、半年くらいたって消す。必要なものは、浅い階層に変える、という対応をとる。このなかで一番ありそうなのは「適当な階層でアーカイブをかける」という奴だろう。簡単に見えて難しい。なぜなら、
・パス名が長くてそのままではアーカイブできない。
・同じフォルダの配下にある別のファイルから対象だけを抜き出さなければならない。
・階層構造の情報を持たせたままアーカイブかけないといけない。

 なに、簡単そうだって?そうです。試行錯誤して問題点が分かってからまとめているからね。まあここまで分かれば、やりかたはこんなものかなあ。
・対象ファイル一覧から、例えばローカルディスクにコピーしてくるバッチファイルを作って、そのときに途中の階層を省略するようにして、
・対象ファイル一覧から、それらを削除するバッチファイルを作って、作業結果確認後に流して、
・ローカルにコピーしたフォルダ構造を、適当にまとめてZIPでまとめて、元のドライブに書き戻してやればよい。
 手間は大変そうだが、こんなもんかな?と思った人、不正解。ファイルをコピーする前に、受け側にディレクトリ構造を作らないといけない。パス名を引っ張り出して、ソートかけてuniqかけて、パス名の一部を変更したバッチファイルを流す。ほら、大変だろう。

 というわけで、本来大問題の256超パス問題、いつものように、何事もなかったかのように、解決されてしまったのでした。おしまい。あーつまらん。具体的手順書は省略。MS-Excelでバッチを作成しまくりという7〜8ページのものになってしまったのだ。
 くれ、という人がいれば考えるが、いないんだろうなあ。地道ながら大事なことだとおもっているんだが、やはり私の感覚は狂っているらしい。

コンピュータネタ、目次
ホーム