Is there a way to enumerate files by creation time on an SMB share?

Viewed 501

I'm looking for a way to retrieve files newer than a certain date/time on an SMB remote share, all working under Windows. I've been using DirectoryInfo.EnumerateFiles(), and filtering as they are returned. Unfortunately, this means every file record is being sent over the network before I look at it, and as the file list grows, this gets progressively worse.

I'm stuck working with a third party vendor such that I don't have the option of removing old files, and I can't run any code on the file server I'm reading from.

I've been able to get some temporary improvement by p/invoking FindFirstFileEx/FindNextFile and using the FindExInfoBasic and FIND_FIRST_EX_LARGE_FETCH flags, but ideally, I'd like to offload the datetime filter to the server and only send the file records I need over the network. Is there some API I'm just not finding that could help?

2 Answers

The SMB protocol itself allows to create a SMB2 QUERY_DIRECTORY Request which gets answered with a SMB2 QUERY_DIRECTORY Response. According to the SMB protocol specification, you should be able to get a list of files of a directory, containing only the minimal set of information you need ("FileInformationClass") and transmitting them in large chunks.

To get an idea of how to implement it, I would take a look at the source code of SharpCifs.Std.

Have you tried this?

DirectoryInfo DirInfo = new DirectoryInfo(@"\\archives1\library\");

DateTime StartOf2009 = new DateTime(2009, 01, 01);

// LINQ query for all files created before 2009.
var files = from f in DirInfo.EnumerateFiles()
       where f.CreationTimeUtc < StartOf2009
       select f;

// Show results.
foreach (var f in files)
{
  Console.WriteLine("{0}", f.Name);
}
Related