优化选择具有相同名称的多个文件中的最新文件的功能

问题描述 投票:0回答:1

我想检查从.drw文件创建的文件是否早于drw本身(这意味着drw已被修改)。

生成文件(如pdf,hp2,pvz等)的srcipt不会覆盖它们,但是如果已经存在同名文件,则在文件扩展名后添加一个新数字。因此,我只想将最新文件(例如test.prt.12)与test.drw文件进行比较。

我编写了一个函数,该函数循环访问与drw同名的文件列表,并检查列表中是否包含重复项。如果是这样,则比较文件的时间戳,以便从列表中删除较旧的文件。

您可以通过创建一个包含几个文件(例如test.txt.1test.txt.2test.txt.3)的文件夹来运行此代码,然后进行更改下面的可复制示例的第一行中的路径到包含测试文件的文件夹。

DirectoryInfo dInfo = new DirectoryInfo(@"C:\Users\me\Desktop\testfiles");  //path to testfiles
List<FileInfo> files = dInfo.EnumerateFiles("*test*").ToList();             //all the files with the same name as the drw
List<string> files_dist = new List<string>();

foreach (var fi in files)                                                   //cut off numbers (test.drw.13 -> test.drw)
    files_dist.Add(fi.ToString().Split('.')[0] + "." + fi.ToString().Split('.')[1]);

while (files.Count() > files_dist.Distinct().Count())                      //while files contains more elements than it would contain without the duplicates
{
    for (int i = 0; i < files.Count(); i++)                                //create loop for array values
    {
        for (int j = i + 1; j < files.Count(); j++)                        //create nested loop
        {                                                                  //if duplicates exist (without any numbers after the file extension)
            if ((files[i].ToString().Split('.')[0] + "." + files[i].ToString().Split('.')[1]) ==
                (files[j].ToString().Split('.')[0] + "." + files[j].ToString().Split('.')[1]))
            {
                MessageBox.Show(files[i] + " and " + files[j] + " have the same filename.");
                if (files[i].LastWriteTime < files[j].LastWriteTime)       //compare time (we dont know the order of the elements)
                {
                    MessageBox.Show(files[i] + " needs to be deleted. It is older than " + files[j]);
                    files = files.Where(val => val != files[i]).ToList();  //delete older element
                }
                else if (files[j].LastWriteTime < files[i].LastWriteTime)  //compare time (we dont know the order of the elements)
                {
                    MessageBox.Show(files[j] + " needs to be deleted. It is older than " + files[i]);
                    files = files.Where(val => val != files[j]).ToList();  //delete older element
                }
            }
        }
    }
}

该代码有效,但是很慢。

我有一个示例目录,其中包含约10.000个文件,该函数在58秒钟内处理完毕。不幸的是,在处理期间没有任何显示,因为图形输出仅在处理完所有文件之后显示。我正在考虑更改输出,以便在处理完数据后逐行打印。最好找到一种方法来推进代码并缩短循环。

我也尝试选择索引最大的文件,并将嵌套循环中的if语句更改为此:

if (Convert.ToInt32(files[i].ToString().Split('.')[2]) < Convert.ToInt32(files[j].ToString().Split('.')[2]))
     files = files.Where(val => val != files[i]).ToList();
else if (Convert.ToInt32(files[j].ToString().Split('.')[2]) < Convert.ToInt32(files[i].ToString().Split('.')[2]))
     files = files.Where(val => val != files[j]).ToList();

但是那并没有明显影响处理时间。

是否有一种简单的方法可以简化代码以节省时间和资源?如何缩短嵌套循环?非常感谢!

c# file optimization timestamp fileinfo
1个回答
0
投票

只是在黑暗中开枪,希望这就是您想要的。我尝试优化您的代码,希望对您有所帮助。

var di = new System.IO.DirectoryInfo("YOURPATH");
        var filesfromdirectory = di.GetFiles("*yoursearchterm*");
        Dictionary<string, FileInfo> files_dist = new Dictionary<string, FileInfo>();
        foreach (var file in filesfromdirectory)
        {
            string currentFileName = file.Name.IndexOf(" (") > 0 ? $"{file.Name.Substring(0, file.Name.IndexOf(" ("))}{file.Extension}" : file.Name;
            if (files_dist.TryGetValue(currentFileName, out var lastWrite))
            {
                if (file.LastWriteTimeUtc > lastWrite.LastWriteTimeUtc)
                {
                    files_dist.Remove(currentFileName);
                    files_dist.Add(currentFileName, file);
                }
            }
            else
                files_dist.Add(currentFileName, file);
        }
        List<FileInfo> ifyouwantlist = files_dist.Values.ToList();
© www.soinside.com 2019 - 2024. All rights reserved.