2017-04-07 10 views
2

Directory.EnumerateFilesを使用しているときに、ファイルやディレクトリを削除または移動することは安全ですか?このようなファイルシステムを列挙している間に削除または移動することは安全ですか?

何か:私は一般的に、あなたはあなたが列挙しているものを変更することになっていない、ということを知っている

foreach (var fileName in Directory.EnumerateFiles("Sub")) 
    File.Delete(fileName); 

。しかし、上記のコードが動作するので、ファイルシステムはそのルールに従っていないようです。

EnumerateDirectoriesおよびEnumerateFileSystemEntriesに同じ質問が適用され、同様の問題がDirectoryInfoクラスの同等のメソッドに適用されます。

+3

関連:[反復中にディレクトリコンテンツが変更された場合、Directory.EnumerateFilesはどうなりますか?](http://stackoverflow.com/questions/29555761/what-happens-with-directory-enumeratefiles-if-directory-content-changes -during-i) – stuartd

+1

あなたが話しているルールは 'foreach'で基礎となるコレクションを変更することに適用されます。これは'IEnumerator'を無効にするためです。この場合、基礎となるデータはコレクションにはなく、より多くのファイル名のストリームのように配信されます。あるいは、 'GetFiles'を使用した場合、基本となるコレクションは配列ですが、削除する配列は変更していません。 – juharr

+0

列挙中にリスト内のオブジェクトを削除または移動するときは、(i = length - 1、i> = 0、i--)のリストを逆方向に移動する必要があります。問題は、インデックスを作成しているアイテムを削除したときです。アイテム2を削除すると、アイテム3は2になり、列挙の中でオリジナルアイテム3をスキップします。 – jdweng

答えて

1

はい、このような列挙中に現在のファイルを安全に削除できます(少なくともWindowsでは)。 Directory.EnumerateFilesは、内部で(ウィンドウ上で)FindFirstFileFindNextFile winapi呼び出しによって実装されています。最初にFindFirstFileが呼び出され、各イテレーターの前進(MoveNext()) - FindNextFileが呼び出されます。これらの呼び出しの間にファイルが削除された場合、そのAPIは問題ありません。FindNextFileは、次の一致するファイルを返します。あなたのケースでは、何もスキップされないように現在のファイルを削除します。新しいファイルが列挙の途中で追加された場合、それが含まれるかどうかはその名前に依存します。既に "b.txt"と "c.txt"というファイルがあり、 "a.txt"というファイルが追加されているとします。このようなファイルは、Directory.EnumerateFilesを使用してインクルードされません。その名前は、すでに列挙されているファイルの名前が「less」(ある意味)です。返信順序はそれほど単純ではありません(ファイルシステムに依存します)が、あなたはその考えを持っています。

+0

少し違います:GetFilesが異なるAPI呼び出しを使用しているかどうか知っていますか?つまり、EnumerateFilesとは少し異なりますか?または、GetFilesが返す前にすべてを列挙するという唯一の違いは何ですか? –

+1

@relatively_random yes GetFilesは全く同じapiを使用します。実際には、 'GetFiles'は基本的に' return EnumerateFiles(path).ToArray() 'を行います。文字どおりではありませんが、同じ方法を実行することになります。 – Evk

関連する問題