how to get the oldest file in a directory fast usi

2020-07-05 06:02发布

I have a directory with around 15-30 thousand files. I need to just pull the oldest one. In other words the one that was created first. Is there a quick way to do this using C#, other than loading them into a collection then sorting?

标签: c# .net file-io
9条回答
Melony?
2楼-- · 2020-07-05 06:33

Look, would it not be easier to shell out to a hidden process and redirect the output stream to the input and use the dir /o-d which sorts by the date/time, using the dash reverses the operation....

Edit: here's a sample code to do this...quick and dirty...

public class TestDir
    {
        private StringBuilder sbRedirectedOutput = new StringBuilder();
        public string OutputData
        {
            get { return this.sbRedirectedOutput.ToString(); }
        }
        public void Run()
        {
            System.Diagnostics.ProcessStartInfo ps = new System.Diagnostics.ProcessStartInfo();
            ps.FileName = "cmd";
            ps.ErrorDialog = false;
            ps.Arguments = string.Format("dir {0} /o-d", path_name);
            ps.CreateNoWindow = true;
            ps.UseShellExecute = false;
            ps.RedirectStandardOutput = true;
            ps.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;

            using (System.Diagnostics.Process proc = new System.Diagnostics.Process())
            {
                proc.StartInfo = ps;
                proc.Exited += new EventHandler(proc_Exited);
                proc.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(proc_OutputDataReceived);
                proc.Start();
                proc.WaitForExit();
                proc.BeginOutputReadLine();
                while (!proc.HasExited) ;
            }
        }

        void proc_Exited(object sender, EventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("proc_Exited: Process Ended");
        }

        void proc_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
        {
            if (e.Data != null) this.sbRedirectedOutput.Append(e.Data + Environment.NewLine);
            //System.Diagnostics.Debug.WriteLine("proc_OutputDataReceived: Data: " + e.Data);
        }
    }

The very first 4 or 5 lines of the StringBuilder object sbRedirectedOutput can be chopped out,then after that line would contain the oldest filename and would be quite easy to parse out....

查看更多
戒情不戒烟
3楼-- · 2020-07-05 06:37

Sorting is O(n log n). Instead, why don't you just enumerate the directory? I'm not sure what the C# equivalent of FindFirstFile()/FindNextFile() is, but you want to do is:

  • Keep the current lowest date and filename in a local variable.

  • Enumerate the directory.

    • If the date on a given file is less than the local variable, set the local variable to the new date and filename.
查看更多
萌系小妹纸
4楼-- · 2020-07-05 06:44

Here's a C# routine that may do what you want by spawning a cmd shell execute a dir /o:D on the specified directory and returning the name of the first file found.

        static string GetOldestFile(string dirName)
        {
            ProcessStartInfo si = new ProcessStartInfo("cmd.exe");
            si.RedirectStandardInput = true;
            si.RedirectStandardOutput = true;
            si.UseShellExecute = false;
            Process p = Process.Start(si);
            p.StandardInput.WriteLine(@"dir " + dirName + " /o:D");
            p.StandardInput.WriteLine(@"exit");
            string output = p.StandardOutput.ReadToEnd();
            string[] splitters = { Environment.NewLine };
            string[] lines = output.Split(splitters, StringSplitOptions.RemoveEmptyEntries);
            // find first line with a valid date that does not have a <DIR> in it
            DateTime result;
            int i = 0;
            while (i < lines.Length)
            {
                string[] tokens = lines[i].Split(' ');
                if (DateTime.TryParse(tokens[0], out result))
                {
                    if (!lines[i].Contains("<DIR>"))
                    {
                        return tokens[tokens.Length - 1];
                    }
                }
                i++;
            }

            return "";
        }
查看更多
登录 后发表回答