Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
483 views
in Technique[技术] by (71.8m points)

c# - What happens with Directory.EnumerateFiles if directory content changes during iteration?

I've read discussions about difference between Directory.EnumerateFiles and Directory.GetFiles.

I understand that internally they both use System.IO.FileSystemEnumerableFactory.CreateFileNameIterator()

The difference is that EnumerateFiles might use deferred execution (lazy), while GetFiles() does a ToArray, so the function is already executed.

But what happens if files and folders are added to the dictionary during the iteration. Will the iteration only iterate over the items that were present during the EnumerateFiles()?

Even worse: what happens if files are removed during iterations: will they still be iterated?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Thanks Michal Komorowski. However when trying his solution myself I saw a remarkable distinction between Directory.EnumerateFiles and Directory.GetFiles():

Directory.CreateDirectory(@"c:MyTest");
// Create fies: b c e
File.CreateText(@"c:MyTest.txt").Dispose();
File.CreateText(@"c:MyTestc.txt").Dispose();
File.CreateText(@"c:MyTeste.txt").Dispose();

string[] files = Directory.GetFiles(@"c:MyTest");
var fileEnumerator = Directory.EnumerateFiles(@"c:MyTest");

// delete file c; create file a d f
File.Delete(@"c:MyTestc.txt");
File.CreateText(@"c:MyTesta.txt").Dispose();
File.CreateText(@"c:MyTestd.txt").Dispose();
File.CreateText(@"c:MyTestf.txt").Dispose();

Console.WriteLine("Result from Directory.GetFiles");
foreach (var file in files) Console.WriteLine(file);
Console.WriteLine("Result from Directory.EnumerateFiles");
foreach (var file in fileEnumerator) Console.WriteLine(file);

This will give different output.

Result from Directory.GetFiles
c:MyTest.txt
c:MyTestc.txt
c:MyTeste.txt
Result from Directory.EnumerateFiles
c:MyTest.txt
c:MyTestd.txt
c:MyTeste.txt
c:MyTestf.txt

Results:

  • GetFiles still saw the old files: B C E as expected
  • EnumerateFiles saw the new files D and F. It correctly skipped the deleted file C, but it missed the new file A.

So the difference in usage between EnumerateFiles and GetFiles is more than just performance.

  • GetFiles returns the files that were in the folder the moment you called the function. Which could be expected, because it's just an enumeration over a string collection
  • EnumerateFiles correctly skips deleted files, but doesn't see all added files. If the folder changes while enumerating the result is fairly undefined.

So if you expect that your folder changes while enumerating carefully choose the desired function

  • Expect GetFiles to see deleted files
  • Expect EnumerateFiles to miss some of the new files.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...