【问题标题】:Delete multiple files while only keeping the newest files with many different file names删除多个文件,同时只保留具有许多不同文件名的最新文件
【发布时间】:2016-01-06 15:56:29
【问题描述】:

我有一个包含许多不同文件名的文件夹,格式为 (filename.extension.indexnumber) 我想保留每个文件名的 3 个最新文件并删除其余文件。这是我用来编译文件列表的代码。

string dir = Convert.ToString(folderBrowserDialog1.SelectedPath);
DirectoryInfo di = new DirectoryInfo(dir);
int asm = comboBox1.SelectedIndex + 1;
int prt = comboBox2.SelectedIndex + 1;
int drw = comboBox3.SelectedIndex + 1;

var assembliesToBeDeleted = (from a in di.GetFiles("*.asm.*", SearchOption.TopDirectoryOnly)
        orderby a.LastWriteTime descending, a.Name ascending
        select a).ToArray();

foreach (var assembly in assembliesToBeDeleted)
{
    //assembly.Delete();
}

我最终得到的列表如下所示:

scumbox_ga.asm.338
scumbox_ga.asm.337
manway_nozzle.asm.3
inputcheck.asm.452
inputcheck.asm.451
inputcheck.asm.450
inputcheck.asm.449
inputcheck.asm.448
inputcheck.asm.447
cover_w_holes.asm.10
cls_halftank.asm.426
cls_halftank.asm.425
cls_half_final.asm.423
cls_half_final.asm.422
cls_half_final.asm.421
cls_half_final.asm.420
cls_half_final.asm.419
cls_half_final.asm.418
cls_half_final.asm.417
cls_half_final.asm.416
cls_half_final.asm.415
cls_half_final.asm.414
cls_half_final.asm.413
cls_half_final.asm.412
cls_half_final.asm.411
cls_half_final.asm.410
cls_half_final.asm.409

我希望这可以澄清问题。

【问题讨论】:

  • I want to keep the 3 newest files of each filename 这对于基于 Windows 的系统没有意义吗?你能改写一下这个问题吗?
  • 我们是否可以假设以“004”结尾的文件比以“003”结尾的文件(具有相同的基本名称)最新?
  • 我过去所做的是将最新的文件保留为基本文件,我还制作了一个副本,并在文件名上附加了时间戳。当我想清理文件时,我会使用它来确定保留数据的时间。这和你问的有点不同,但也许它会给你一个想法。
  • 最好等待OP的澄清。如果此说明附有要删除而不是要删除的文件的示例,那就更好了。
  • 当您将新文件另存为备份类型时,程序会分配最终索引号。变量“assembliesToBeDeleted”是包含所有文件的列表。例如,我的数组中有以下文件(1.asm.1、1.asm.2、1.asm.3、1.asm.4、2.asm.7、2.asm.8、 2.asm.9、2.asm10)。最高索引号将是每个基本文件名的最新文件。

标签: c# file-management


【解决方案1】:

我认为您正在寻找的方法是:

File.Delete(assembly);

定义:here

所以你的代码最终看起来像:

string dir = Convert.ToString(folderBrowserDialog1.SelectedPath);
DirectoryInfo di = new DirectoryInfo(dir);
int asm = comboBox1.SelectedIndex + 1;
int prt = comboBox2.SelectedIndex + 1;
int drw = comboBox3.SelectedIndex + 1;
var assembliesToBeDeleted = (from a in di.GetFiles("*.asm.*", SearchOption.TopDirectoryOnly)
                                     orderby a.LastWriteTime descending, a.Name ascending
                                     select a).ToArray();
 foreach (var assembly in assembliesToBeDeleted)
 {
      File.Delete(assembly);
      Console.WriteLine(assembly);
 }

【讨论】:

  • 这将删除所有内容
  • 我认为assembliesToBeDeleted 是 OP 要删除的文件。这个问题在某些方面相当令人困惑。希望OP会改写
  • 在变量“assembliesToBeDeleted”中。我想从这个数组中过滤掉每个基本文件名的 3 个最新文件。
【解决方案2】:

假设您的备份过程添加的扩展名被填充为三个字符的扩展名,用零填充缺失的数字

所以有一组具有这种模式的文件

"ABCD.001"
"ABCD.002"
"ABCD.003"
"ABCD.004"
"ABCD.005"

您想保留文件 003、004、005,然后您可以将代码更改为

DirectoryInfo di = new DirectoryInfo(dir);
// Get the distinct base file names of every file in that directory
// So for a bunch of files 'Name.XX1','Name.XX3','Name.XX3' we
// get an IEnumerable of only the Name part
var files = di.GetFiles("*.*", SearchOption.TopDirectoryOnly)
               .Select(x => Path.GetFileNameWithoutExtension(x.Name)).Distinct();

// Now loop over each base file name
foreach (string file in files)
{
    // Get the files with that base name in descending order but skipping the first 3
    var toDelete = di.GetFiles(file + ".*").OrderByDescending(d => d.Name).Skip(3);

    // Delete if any file is in the IEnumerable returned
    foreach(FileInfo fileToDelete in toDelete)
        fileToDelete.Delete();
}

如果您的扩展名没有填充三个字符,那么您应该恢复使用 FileInfo 的 LastWriteTime

var toDelete = di.GetFiles(file + ".*").OrderByDescending(d => d.LastWriteTime).Skip(3);

【讨论】:

    【解决方案3】:

    我会创建一个文件名对象来保存这三个部分。

    class AssemblyFilename
    {
      public string Name { get; set; }
      public string Part { get; set; }
      public int Version { get; set; }
    }
    

    创建一个构造函数来解析出部分

    public AssemblyFilename(string filename) { /*...*/ }
    

    然后你可以使用 LINQ

    var fileGroups = assemblyFilenames.GroupBy(af => af.Name);
    foreach(var group in fileGroups)
    {
      foreach(var filenameToDelete in group.OrderByDescending(g => g.Version).Skip(3))
      {
        // delete
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-04
      • 2017-05-29
      • 2016-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      相关资源
      最近更新 更多