C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[5]: アクセスしなければ値が確定しない


(過去ログ 15 を表示中)

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■5367 / inTopicNo.1)  アクセスしなければ値が確定しない
  
□投稿者/ Gustaf (1回)-(2007/07/11(Wed) 14:29:28)

分類:[VB.NET] 

2007/07/13(Fri) 17:27:30 編集(投稿者)
開発環境:VS2005
言語  :VB.NET

指定したフォルダ内の変更や作成されたファイルを取得し、複製する処理を作成しています。
動作はするようになったのですが、起動時の動作が不可解なので質問させてください。

起動時にファイルリストを取得しているはずなのに
・起動時にファイルリストを取得
・対象フォルダのファイルを変更
・ボタンを押して新たにファイルリストを取得

以上の処理が終わった後、
変更前と変更後のファイルリストを比較しても内容が同じままです。
どうやら起動時にファイルリストがきちんと取れていないようなのですが、
コメント化してある値のチェックを行うことで意図した値が取得できます。

どうにも原因がつかめないので、どなたかアドバイスをお願いします。

' 以下ソース
Imports System.IO
Public Class Form1
    ' ファイルリスト格納用
    Private FileList As New List(Of FileInfo)
    Private Const strTargetFolder = "D:\Data\FolderWatch\1\"

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        ' 既存のファイルリストを取得
        FileList.AddRange(New DirectoryInfo(strTargetFolder).GetFiles)
        ' ------------------------------------------
        ' ここを有効にすることで正しく動作する
        ' 既存のファイルリストを出力
        'For Each f As FileInfo In FileList
        '    Debug.WriteLine(f.Name & ":" & f.Length)
        'Next
        ' ------------------------------------------
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        ' 最新のファイルリストを取得
        Dim NewFileList As New List(Of FileInfo)
        NewFileList.AddRange(New DirectoryInfo(strTargetFolder).GetFiles)
        ' 前回のファイルリストを出力
        For Each f As FileInfo In FileList
            Debug.WriteLine(f.Name & ":" & f.Length)
        Next
        ' 最新のファイルリストを出力
        For Each f As FileInfo In NewFileList
            Debug.WriteLine(f.Name & ":" & f.Length)
        Next
        ' データ更新
        FileList = NewFileList
    End Sub
End Class

引用返信 編集キー/
■5469 / inTopicNo.2)  Re[1]: アクセスしなければ値が確定しない
□投稿者/ Teja (1回)-(2007/07/13(Fri) 23:00:19)
 実行した所、同じ現象が出たので色々確認してみました。
 "New DirectoryInfo(strTargetFolder)"を実行した時点でファイルサイズを調べている
わけではなく、"f.Length"の都度に調べている様です。

 以下手順で確認。
 1."D:\Data\FolderWatch\1\"フォルダ内に適当なファイルを作成。
 2.プログラムを実行。
 3.上記1で作成したファイルを削除。
 4.ボタンを押すと"f.Length"でファイルが無い旨の例外が発生。

 上記確認より、"New DirectoryInfo(strTargetFolder)"ではファイル検索のみしている。
(たぶん、FileInfoを作ってファイル名のみ保存。Listに追加した時点では、ファイル名
 のみ保持している)

 また、フォームロード時にファイルリストを表示した後に、上記確認を行っても例外が
発生しない(ロード時のサイズが表示される)事より、"f.Length"を1度実行した後は
結果を保存し、再度のサイズ確認はしないのだと思います。

 結論:
  ファイルサイズは、最初に"f.Length"を呼んだときのサイズになる。
  ファイルは、"New DirectoryInfo(strTargetFolder)"の実行時に検索。




引用返信 編集キー/
■5471 / inTopicNo.3)  Re[2]: アクセスしなければ値が確定しない
□投稿者/ まどか (330回)-(2007/07/14(Sat) 01:36:26)
仕様がTejaさんの言われるとおりだとしても
「ファイル」という性質上、GetFilesからプロパティ参照までに不定の間隔があくのはよくないのではないでしょうか。
#ファイル入出力処理では存在チェックとIOを連続処理しますよね?
GetFilesの直後ですぐ自前のデータクラスなどへ値を退避しましょう。
引用返信 編集キー/
■5473 / inTopicNo.4)  Re[3]: アクセスしなければ値が確定しない
□投稿者/ なちゃ (47回)-(2007/07/14(Sat) 02:38:16)
MSDNをよく読みましょう。
各種プロパティや、基底クラスのFileSystemInfoの説明に、情報のキャッシュ等について記述があります。

でまあ、そもそもFileInfoとかは指定されたパスのファイルを扱うクラスであって、
コンストラクト時点のファイルの情報のスナップショットを取り出すクラスではありませんから、
まどかさんが書かれているように、必要な時点で取り出して覚えておくのが基本でしょう。

キャッシュの動作上以前の情報を覚えているように動きますが、それはどちらかというと
このクラスの本来の目的の動作とは違うでしょう(あくまで処理効率のための動作)。

引用返信 編集キー/
■5474 / inTopicNo.5)  Re[4]: アクセスしなければ値が確定しない
□投稿者/ なちゃ (48回)-(2007/07/14(Sat) 02:41:25)
って書きましたが、Refleshメソッドの説明とかを見ていると、動作はわりとしっかりスナップショットな扱いっぽいですね。

まあ、直感にも反するのでやっぱり自分で覚えておく方がすっきりするとは思いますが。

引用返信 編集キー/
■5517 / inTopicNo.6)  Re[5]: アクセスしなければ値が確定しない
□投稿者/ Gustaf (2回)-(2007/07/17(Tue) 11:40:17)
Tejaさん、まどかさん、なちゃさん
回答ありがとうございます。

指摘されたことを元にMSDNを読み直しながら考えてみました。
そもそもFileInfoクラスの使い方がずれていたんですね・・・

GetFile後にそれぞれのファイルをRefreshすれば値が取れることは確認しましたが、
そのままFileInfoに格納するのはやめて、
データクラスに必要な値だけを確保するように修正しようと思います。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -