ファイル移行用バッチファイル作成

 正直なところ「あれ〜?なんで皆さん作ってないの??」である。
 ファイルのコピー、ないし移動ツール。
 組織変更で統廃合されると、OAファイルサーバーに納められたファイルを新組織に合わせたフォルダ構成に移行しないといけない。さすがにショートカットのリンクを置き換えるまでは誰もがやっているわけでなかろうと「リンクつなが〜る」は作ったのだが、ファイル移動だけであれば皆さんお手元に作っていて当然でしょ、と考えるのがいわば常識。

 誰かが代表して作り、組織変更の際に全社に提供、というのが分かりやすいが、だいたいそういうことをすべき担当部署は、ファイルサーバーの移行自体でてんてこ舞い、なので移行に間に合うように(実際に困る)各部署が作る、ということになるのはある程度仕方がない。
 同じ目的を果たすために複数のツールが重複して作られたということになるが、決して無駄ではないのだよ。それらの間には設計方針、完成度の違いというものがあるだろうから、それを前提として、作成者各位が「私はこういうところに注目して、こう作りました」と、そうねえ、パネルディスカッションでもやるといい。それを若手に見学させるのだ。プログラムを作るときに皆がどう考えて作るのか、身近な例で多くの先輩方のやり方を聞く。とてもよい勉強の機会になるに違いない。

 私が作った時に考えたのは。

  1. 移行するファイル/フォルダをどう取得するか?
     まずは移行対象の明細を見なければならない。ようするに移行フォルダを指定して、そこに属するファイル名、パス名の組み合わせの一覧を取得すればいいわけだ。取得部分から自力でプログラムを書く、dirコマンドの出力を編集する、といった手法が考えられるが、当方はフリーソフト「ファイルリスト作成機」の出力を使うことにした。速度的にはdirコマンドを使うほうが優れているかもしれないが、大した差ではないし(計った)そう何回も使うものではない。組織変更の時だけだ。なので、他のプログラムに丸投げした。ツールへの読み込みは、ファイルリスト作成機が出力したテキストファイルをMicrosoft Excel上にコピペするだけであるから大した運用負担ではあるまい。(例によってMicrosoft ExcelのVBAで作ってます。exeファイル作ると社内手続き上、話がややこしくなるので。)
     後から考えると、自分にアクセス権のないフォルダを見つけるためにdirコマンドを見たほうが良かったかな、という気にはなったが。(別件でdirコマンドの出力からファイル&パス一覧を作るツール、アクセス権のないフォルダを洗い出すツールも作っているから言える余裕の反省である。)
     さて、ほかの製作者はどんな風に考えて何を作っただろう。

  2. ファイルの移動をどうするか?
     ストリームを使ってプログラム内部で、というのもやったことはあるが、途中でサーバーが止まったりしてエラーが起こった時の動作を保証しようとすると相当めんどくさいことになるので、xcopyないしmoveするバッチファイルを出力し、実際の移動はそちらに任せることにした。だって、ファイルサーバーをまたがった移行が必要なければ、ストリーム使うより、moveコマンド使ったほうが圧倒的に速いんだもん。
     実行状況の確認はxcopyないしmoveコマンドの出したメッセージをテキストファイルに出力しておけばよい。
     この場合のメリットとしては「移行するファイル数が多すぎて、1台でやるには無理がある」場合、バッチファイルを数人で分割して実行、というのがやりやすいこともあります。
     書き忘れておりましたが、途中で止まった時のことを考えてファイルは一つ一つ移行、ということはフォルダの階層はそれに先立って作っておく必要があって、つまりフォルダ作成のバッチファイルというのもしっかりお作りいたします。
     まあ、このへんまでは他のパネラーの皆さんも「うんうん、わかるわかる」で和やかに進むんでしょうなあ。

  3. どのような異例事態を想定し、どう対処するか?
     パネルディスカッションを見てくれている若手が勉強になるのはここからである。
     私が考えたのは、まずUNCパス長の問題だ。Windowsの仕様ではファイルパス+ファイル名のバイト数が260(256説もあり)を超えるとOSとして扱えなくなる。(NTFS自体はもっといけるらしい。)移行した結果、パスが長くなるとこの制限を超える可能性がある。ほら、ありそうでしょ。移行先に旧組織名のフォルダを置いてその下に既存のファイル、フォルダを納めてゆくというやりかた。なぜか場合によっては260を超えるパスも作れたりするのでややこしいし、「できるんだからいいじゃないか」という人もいないわけではない。が、そう言う人たちであっても「仕様は260バイトだ。それを超えたらバックアップツールが対象としてくれなくても文句は言えないけど、それでもいいの?」と尋ねるとせっせと手作業で短くしてくれるものです。
     というわけで、移動(ないしコピーの)バッチファイルを作る際は「移動先のパス長が256バイトを超えないかのチェック」をかまし、超えた場合はその行の先頭に
    REM フルパス長が長すぎます
    の文言を入れるようにいたしました。
     次に考えたのは「移動先に移動させようとしたのと同名のファイル(フォルダも)があったときに備える」。途中でバッチが止まったら後が面倒だし、上書きしちゃったら目も当てられない。なので「バッチファイルを作る際に、あらかじめ移動先に同名のファイルがないかチェックする」機能を作りこみました。はい、遅くなります。なのでソースに定数でチェックするかどうかのフラグを立てておくようにします。(最終的には必ずチェックする、になるんだけど、それだとテストに時間がかかりすぎるから。← 我ながらホントよく考えてるよ。)ちなみに同名のファイルがあると、その行はREMつけてコメントとする。わかりやすいようにセルを赤で塗る。
     最後は、特定の列をコピーして、テキストファイルにそのまま貼り付け。拡張子を.batにしてセーブすればバッチファイル完成。あとは、できればコマンドラインから実行です。

  4. 設定をどうするか?
     GUIで移行元と移行先のフォルダを指定!というのが使いやすそうで受けがいいですが、今回はプログラムソースに定数として埋め込みました。理由は単純で「複数人により確認ができる」。GUIだと記録が残らないから難しいのです。
     なお、ドライブレターを使っている場合に備え(というか「ファイルリスト作成機を使っている段階でファイルサーバー上のフォルダにドライブレターを割り当てるのが前提となる)、ドライブレターとそれを割り振ったUNCパスの長さの差を定数で指定するようにしております。めったに使わない、しかし失敗しちゃったらリカバーが大変という場合には「手が滑った程度では変更できない」ところに設定は押し込めておいたほうがいいと思ったのよ。

  5. ついでに言うと
     複数の組織を統合する際に、OAのファイルサーバーのフォルダも統合するものであるが、よくあるのが先ほども書いたように「旧〇〇部」というサブフォルダを作ってそこに丸ごと移動。「フロアレイアウト」「勤怠管理」といった新組織として共通的に使用するフォルダは改めて浅い階層に作ってゆくやり方である。そのうちに旧組織名にぶら下がったフォルダは使われなくなって徐々に消えてゆくことを期待しているのであろうが、消える前に人が入れ替わると「誰も消せなくなる(消す判断ができなくなる)」。(最終更新日以後に作成されて、あるいは親フォルダの作成日以前に作成されて、作成日以後一度もアクセスされてないファイルを一覧表にする程度のツールは作ったが。)
     なので強引に同一レベルのフォルダにコピーすることを考えたわけよ。そのときに問題となるのは「フォルダ名ないしファイル名のバッティング」。だからこれをバッチファイルを作る時点で確認し、問題があればワーニングを出すようにしたのよ。
     どうしても同一名称になる場合や、フォルダ名の頭に番号付けてわかりやすくしている例もあると思うが、その場合は「バッチファイル」つまり「テキスト」なのだから、フォルダ名の部分を一括で置換する、のは難しくないはず。
     実はここまで考えてこの仕様にしているのであります。
 以上の仕様と作りこみ、なかなか自信を持っていたのだが、さらに効果的な計算ができる人がいたようだ。WindowsのエクスプローラーからDrag&Dropで移行するのである。これをやると移動の途中で使用中のファイルに行き当たると「そこで処理が終わってしまう」という問題点がある。ではどうするか?他の人がいないときに動かせばよい。つまり残業手当の高い夜間、代休がとれてのんびりできる休日に行うこととなる。「楽をしよう」とツールを作った私の発想は方向性からして間違っていたようだ。
フリーソフト開発秘話、目次
ホーム