none
DirectoryInfoクラスのインスタンス内のFileInfo.LastWriteTimeプロパティ RRS feed

  • 質問

  • DirectoryInfoクラスのインスタンス内のFileInfo.LastWriteTimeプロパティについてご教示願いたいのですが

    DirectoryInfoクラスをNewコンストラクタでインスタンス化し

    DirectoryInfo.GetFilesによりFileInfoを列挙しながら、該当ファイルの更新日時を
    取得しようとしております。


    例としてコードを載せます。

    Dim dirPath As System.String = "\\hostName\work"    'WAN越しの端末の共有フォルダ
    Dim fileAr As New System.Collections.Generic.Directory(Of System.String, System.String)
    Dim di As New System.IO.DirectoryInfo(dirPath)
    
    For Each fi As System.IO.FileInfo In di.GetFiles
        fileAr.Add(fi.Name, fi.LastWriteTime.ToString("yyyyMMddHHmmss"))
    Next
    


    みたところ、fi.LastWriteTime.ToString("yyyyMMddHHmmss") の実施に際して時間が掛かっているようでした
    (要は指定ファイルに、毎回物理的にネットワーク回線を介しアクセスし情報を取得している?かの様)

    ただし私の解釈では、
    Dim di As New System.IO.DirectoryInfo(dirPath) によりDirectoryInfoクラスのインスタンスが生成されるタイミングでは
    実際のパス上の情報を通信で取得する為にコストが掛かるが
    一度インスタンス化されたDiredtoryInfoクラスのオブジェクト内にはディレクトリ配下のファイルの情報を含む
    FileInfo情報も合わせて実体化されて保存されており、以降の For Each ループなどでのFileInfo情報の列挙を行った場合も
    実際のファイルシステム上のファイルにアクセスすることなく更新日時などはDirectoryInfoクラスインスタンスオブジェクト内から
    取得できるものだと考えておりました。
    この解釈は誤っているのでしょうか?

    2012年3月1日 9:49

回答

  • DirectoryInfo が実際にファイルにアクセスするのは、インスタンス生成時ではなく、何らかのプロパティを初めて参照するときのはずです。

    // ドキュメントでは「最初に呼び出されたとき」なんて曖昧な記述になってますが。

    • 回答としてマーク RNC-COM 2012年3月2日 3:53
    2012年3月1日 10:18
  • 基本的にはHongliangさんの書かれている通りなのですが、重要な追加情報があります。

    .NET Framework 4 の基本クラス ライブラリの新機能で紹介されていますが、.NET 4ではDirectoryInfo.EnumerateFilesメソッドが追加されています。こちらを使いますと、全ファイルが取得できる前に逐次FileInfoが返される上に、LastWriteTimeを含むいくつかのプロパティが設定された状態で取得できます。詳しくはリンク先を参照してください。

    • 編集済み 佐祐理 2012年3月1日 13:00
    • 回答としてマーク RNC-COM 2012年3月2日 3:51
    2012年3月1日 13:00

すべての返信

  • DirectoryInfo が実際にファイルにアクセスするのは、インスタンス生成時ではなく、何らかのプロパティを初めて参照するときのはずです。

    // ドキュメントでは「最初に呼び出されたとき」なんて曖昧な記述になってますが。

    • 回答としてマーク RNC-COM 2012年3月2日 3:53
    2012年3月1日 10:18
  • 基本的にはHongliangさんの書かれている通りなのですが、重要な追加情報があります。

    .NET Framework 4 の基本クラス ライブラリの新機能で紹介されていますが、.NET 4ではDirectoryInfo.EnumerateFilesメソッドが追加されています。こちらを使いますと、全ファイルが取得できる前に逐次FileInfoが返される上に、LastWriteTimeを含むいくつかのプロパティが設定された状態で取得できます。詳しくはリンク先を参照してください。

    • 編集済み 佐祐理 2012年3月1日 13:00
    • 回答としてマーク RNC-COM 2012年3月2日 3:51
    2012年3月1日 13:00
  • そうなのですね。

    IDEのウォッチなどで表示させると、GetFilesのコレクションは全て詰まって見えていたので(これって見かけだけなんでしょうねw)

    実際もコレクション内は有効なのかともおもってました

    ありがとうございました

    2012年3月2日 2:56
  • 確かに、書かれていますね。

    そういう意味では、「DirectoryInfo.EnumerateFiles」を使用することで幾分改善される可能性もあったわけですが

    実際、弊社のアプリの必要要件として.NET Framework 4 を必須用件としていないこともあり、このメソッドを使った

    コーディングは出来ないかな...とも考えています。

    どちらにせよ、今後の開発に参考にさせていただきます。

    ありがとうございました。

    • 回答としてマーク RNC-COM 2012年3月2日 3:00
    • 回答としてマークされていない RNC-COM 2012年3月2日 3:52
    2012年3月2日 3:00
  • IDE のウォッチ式なども、「プロパティを参照する」動作を含みますから。
    2012年3月2日 3:08
  • # 参考にされるのでしたら「参考になった投稿として投票」してほしいなぁ~。ついでに回答としてマークしてもらえてもいい気がしますが。

    内部事情として、GetFilesやEnumerateFilesはWindows APIのFindFirstFile / FindNextFileを使います。ここで取得できるWIN32_FIND_DATAにはもともとLastWriteTimeなどが含まれていましたが、GetFilesではこれらの情報は読み捨ててファイル名ぐらいしか使用していませんでした。ここをちゃんと使おうというのがEnumerateFilesです。

    .NET 4を使用されていないとのことですので、この場合に効率よく処理されたいということでしたら、FindFirstFileなどWindows APIを直接呼び出すしかないでしょう。

    2012年3月2日 3:44