2012-04-04 6 views
0

Windows Server 2008と比較してWindows Server 2008のファイルに連続して書き込むと、奇妙な動作に気がつきました。Windows Server 2008でファイルサイズが変更されない

私はいくつかのスレッドからそのような何かを実行します。私は総司令官とWindowsエクスプローラでファイルを観察するとき、私はファイルサイズが一定に保つことがわかり

using (var fi = File.Open(...)) 
{ 
    using (var fw = new StreamWriter(fi)) 
    { 
     while program-is-running 
     { 
      fw.WriteLine(some-data); 
      fw.Flush(); 
     } 
    } 
}    

を。 Windowsエクスプローラで手動でディレクトリコンテンツを更新するまでファイルのサイズが一定(合計コマンダーとWindowsエクスプローラで)に固定されていますF5

Windows XPで同じプログラムを実行すると、Total CommanderとWindows Explorerが連続してファイルサイズが増加していることを示します。

何が問題なのでしょうか。それはNTFSの動作、ソフトウェアの設定などですか?

ありがとうございます!

+0

は確かに言うことはできませんが、一部のキャッシュメカニズムがそれを作る可能性があります。 –

答えて

3

this article)を参照してください。The Old New Thing。基本的には効率と関係があります。最新のファイルメタデータ(サイズなど)は、ディレクトリエントリではなくファイル自体に格納されます(これは、一部のUNIXファイルシステムの仕組みと同じですが、古いFATメソッドとは対照的です)。

ただし、サイズは定期的にディレクトリエントリに転送されるため、「最後にわかった」値を取得できます。そして、ある時点(ファイルの変更が停止した後)で、最後の既知の値が正確になります。その記事から

:メタデータのいくつかは、ディレクトリを改善するための微調整として、ディレクトリエントリに複製してNTFSファイルシステムのメタデータで

は、いないディレクトリエントリのではなく、ファイルのプロパティであります列挙パフォーマンス。 FindFirstFileのような関数はディレクトリエントリを報告し、FATユーザが "無料で"入手するのに慣れていたメタデータを置くことによって、ディレクトリリストのFATよりも遅くならないようにすることができます。ディレクトリ列挙関数は、最後に更新されたメタデータを報告します。これは、ディレクトリエントリが古くなった場合に実際のメタデータに対応しない可能性があります。

次の質問は、このメタデータ複製の実行場所と頻度です。言い換えれば、このデータはどれくらい失効していますか?ファイルのメタデータが変更されるたびに無限の数のディレクトリエントリを更新する必要がなくなるように、NTFSではファイルを開くために使用されたディレクトリエントリにのみファイルからのレプリケーションが実行されることになりました。つまり、ファイルに1,000個のハードリンクがある場合、ファイルサイズの変更はファイルを開くために使用されたディレクトリエントリに反映されますが、他の999個のディレクトリエントリには古いデータが含まれます。

Windows Vista(およびそれに対応するWindows Serverのバージョンではわかりませんが、私はあなたがルックアップでき、 "あなた"は "Yuhong Bao"を意味します)から、NTFSファイルシステムはこれを実行しますファイルオブジェクトの最後のハンドルが閉じられたときの礼儀複製。以前のバージョンのNTFSでは、キャッシュがフラッシュされるたびにファイルが開いている間にデータがレプリケートされたため、予測できないスケジュールに従って頻繁に発生しました。この変更の結果、ディレクトリエントリの更新頻度が低下するため、最終更新日時のファイルサイズがすでに更新されている日付よりも古いです。

0

開いているファイルの正しいファイルサイズを取得するためにWMIを使用することができます。

Using System.Management; 

internal static ManagementObject GetFileManagementObject(string pfilepath) 
     { 
      string filepath = pfilepath.Replace("\\", "\\\\"); 
      string scope = @"\\" + System.Environment.MachineName + @"\root\CIMV2"; 
      string query = string.Format("Select FileSize from CIM_DataFile WHERE Name  = '{0}'", filepath); 
      ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query); 
      ManagementObjectCollection collection = searcher.Get(); 
     foreach (ManagementObject mobj in searcher.Get()) 
     { 
      return mobj; 
     } 


     return (null); 
    } 

private long GetFileSizeOpenFile(string path) 
    { 
     long fsize = -1; 
     try 
     { 
      ManagementObject mObj = Statics.GetFileManagementObject(path); 
      string sSize = mObj.Properties["FileSize"].Value.ToString(); 
      long.TryParse(sSize, out fsize); 
     } 
     catch(Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
     return fsize; 
    } 
関連する問題