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

限于喜欢 提交于 2019-11-29 11:35:00

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\b.txt").Dispose();
File.CreateText(@"c:\MyTest\c.txt").Dispose();
File.CreateText(@"c:\MyTest\e.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:\MyTest\c.txt");
File.CreateText(@"c:\MyTest\a.txt").Dispose();
File.CreateText(@"c:\MyTest\d.txt").Dispose();
File.CreateText(@"c:\MyTest\f.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\b.txt
c:\MyTest\c.txt
c:\MyTest\e.txt
Result from Directory.EnumerateFiles
c:\MyTest\b.txt
c:\MyTest\d.txt
c:\MyTest\e.txt
c:\MyTest\f.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.

There is only one way to check:

Directory.CreateDirectory(@"c:\\Temp");
File.Create(@"c:\\Temp\\a.txt").Close();
File.Create(@"c:\\Temp\\b.txt").Close();
File.Create(@"c:\\Temp\\c.txt").Close();
foreach (var f in Directory.EnumerateFiles(@"c:\\Temp"))
{
    Console.WriteLine(f);
    //Let's delete a file
    File.Delete(@"c:\\Temp\\c.txt");
    //Let's create a new file
    File.Create(@"c:\\Temp\\d.txt").Close();
}

Initially C:\Temp contains 3 files: a.txt, b.txt and c.txt. During the iteration one of these file is being deleted and one is being created. Finally, the C:\Temp contains the following files: a.txt, b.txt and d.txt However, in the console you will see the original content of this directory i.e.:

c:\\Temp\a.txt
c:\\Temp\b.txt
c:\\Temp\c.txt
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!