FileSystemInfo クラスっぽい FileSystemEntry クラスを書いてみた
メモどまりの[ってみた]だけじゃあれなので、久しぶりに役に立ちそうな感じのを書いてみるよっ。
FileSystemInfo クラス[msdn.microsoft.com]ってのは、
.NET Framework に入ってる、System.IO 名前空間に入ってるクラスだよ。
前に書いたけど、.NET Framework のファイル / ディレクトリ操作 API は
パスの文字数に制限があって*1、266 文字のパスを扱えなかった。
なので、自分で FileSystemInfo 相当のクラスを作るしかなかったんだよね。
大体わかったので、今度はそれを C++ で書いてみることにしよう。
VS のデバッグ画面で、FileSystemInfo は、_data という WIN32_FILE_ATTRIBUTE_DATA を中に持ってることが分かった。
WIN32_FILE_ATTRIBUTE_DATA って何かというと…
Contains attribute information for a file or directory. The GetFileAttributesEx function uses this structure.
英語*2だけど、コードとプログラミングに使う単語を覚えていればわかるはず。
この構造体は、GetFileAttributesEx 関数で使います、ってことらしい。
でも、どんなタイミングで取り出してるんだろう? FileSystemInfo クラスにはなんて書いてあるかというと
FileSystemInfo では、最初に呼び出されたときに Refresh を呼び出し、属性の取得などを行う API に関するキャッシュされた情報を返します。 以降の呼び出しでは、Refresh を呼び出して、最新の情報を取得する必要があります。
「最初に呼び出されたときに」何が最初に呼び出された時なのか分からないけれど、私はここの記述にインスピレーションを見いだして、書いてみた。
つまり、コンストラクタで、最初の refresh() を呼びだすってこと。
今思いついた方法では、プロパティがアクセスされたときに最初の refresh() を呼びだすんだけど、そっちで書いてみよう。
class FileSystemEntry { protected: FileSystemEntry(const std::string& path) : full_path_(), original_path_(path), data_(NULL), data_initialized_(-1) { } virtual ~FileSystemEntry() { if ( data_initialized_ == 1 ) { delete data_; data_ = NULL; } } public: void refresh() { if ( data_initialized_ == -1 ) { data_ = new WIN32_FILE_ATTRIBUTE_DATA(); data_initialized_ = 1; } /* (1) */ } protected: std::string full_path_; private: std::string original_path_; WIN32_FILE_ATTRIBUTE_DATA* data_; int data_initialized_; };
ソース中の (1) にはいよいよ GetFileAttributesEx を書いて\(ファイル\|ディレクトリ\)情報を取得するコードを書くわけだけど、
また次回ってことで〜。