本サイトはプロモーションを含みます。

ファイルの存在を確認する方法

Tera Termマクロで用意されているfilesearchコマンドはファイルが存在するとシステム変数resultに1を格納しますが、困ったことにそれがディレクトリであっても同じくシステム変数resultに1を格納します。

foldersearchと組み合わせれば良さそうですが、面倒です。どうせなら1度で済ませたいですよね。

という事で、ぼくの解決方法を紹介します。

2016/09/26追記:ぼくの解決方法は正しくなかったので、正しい方法について追記しています。詳細についてはチケット#36643を参照してください。

ファイルステータスを取得するコマンド

filestatはTera Term 4.66以降で使用できるコマンドです。このコマンドは、ファイルのサイズや最終変更時刻、ドライブ番号を取得します。使い方は次のようになります。

filestat <filename> <size> [<mtime>] [<drive>] 

filenameにステータスを取得したいファイル名、sizeはfilenameのファイルサイズが入ります。mtimeとdriveは指定しなくても大丈夫です。

このコマンドは、ファイルステータスの取得に失敗するとシステム変数resultに-1が格納されます。

という事で、このコマンドを使えばファイルの存在確認ができそうですね。サンプルです。

;ファイルの存在を確認するサンプル

; 存在確認するファイル
filename = 'hoge.txt'
size = 0
filestat filename size
if result == -1 then
    messagebox 'ファイルが存在しない' size
else
    messagebox 'ファイルが存在する' size
endif

もしもディレクトリだったら?

これはこれで動くのですが、filestatは万が一ファイルでなくディレクトであった場合でもシステム変数resultは-1にならず、ファイルが存在するときと同様に0が格納されます。

ファイルとディレクトリを一発で判別する正しい方法

チケット#36643で紹介されているマクロは以下のようなものです。

name = "C:\test"

getfileattr name

if result < 0 then
    messagebox "not found" name
elseif result & $10 then
    messagebox "directory" name
else
    messagebox "file" name
endif

getfileattrはTera Term 4.69以降で使う事ができるTTLコマンドです。次のように使います。

getfileattr <filename>

filenameで指定したファイルの属性を取得します。属性の取得に失敗した場合はシステム変数resultに-1が格納されます。成功すると、属性値がシステム変数resultへ格納されます。

属性値 意味
$1 読み取り専用
$2 隠しファイルまたは隠しディレクトリ
$4 オペレーティングシステムの一部、またはオペレーティングシステム専用
$10 ディレクトリ
$20 アーカイブ
$80 特に属性はない
$100 一時ファイル
$200 スパースファイル
$400 再解析ポイントが関連付けられているか、シンボリックリンク
$800 圧縮されている
$1000 オフラインの記憶装置へ物理的に移動された(Windows 2000 以降)
$2000 「インデックスサービス」の対象になっていない(Windows 2000 以降)
$4000 暗号化されている

属性値の頭に「$」が付いているのは、16進数という意味です。値の判定に使っている箇所

elseif result & $10 then

この「&」はビット演算子です。「&&」とは意味が違うので注意してください。ビット演算子はTera Term 4.53以降で使う事ができます。16進数やビット演算子についてピンと来ない方もいるかと思いますが、分からなくても大丈夫です。「result & $xxx」で属性が取得できる、という理解で十分です。「$xxx」の箇所は上の表に書いてある値を入れます。たとえば読み取り専用か知りたければ「result & $1」で調べる事ができます。

ぼくが紹介していた正しくない方法

2016/09/26追記:この方法、今のところは動くのですが正しいやり方ではありません。今後仕様変更があった際に誤作動を招く恐れがあるので、真似しないで下さいね!

では、どうやって解決すれば良いのかというと、ディレクトリの場合はsizeに0が格納されます。ですので、システム変数resultとファイルサイズが両方とも0であった場合はディレクトリ、システム変数resultが0でファイルサイズが0超過であればファイルであると判断できます。サンプルです。

;ファイルの存在を確認するサンプル

; 存在確認するファイル
filename = 'hoge.txt'
size = 0
filestat filename size
if result == -1 then
    messagebox 'ファイルが存在しない' size
elseif result == 0 && size == 0 then
    messagebox 'ディレクトリです' size
else
    messagebox 'ファイルが存在します' size
endif

さいごに

getfileattrについては、完全に見落としていました。これならばファイルなのか、ディレクトリなのか、といった判別だけでなく属性を調べる事ができるので応用範囲が広がりそうです。

2016/09/18追記

昨日(2016/09/17)、OSDNにこのページに関するチケットが上がっていました。

チケット #36643 ディレクトリ存在判別

3 COMMENTS

shj

ご指摘ありがとうございます。記事を修正しました。ぼくと同じような事をしている人がいるかも知れないので、正しくない方法は削除せずに悪い例として残しています。

返信する

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)