如何排序和删除特定文件?

时间:2013-08-07 13:27:46

标签: c# winforms file-io

(我没有意识到长篇文章不受欢迎)

我的程序读取的文件目录类似于以下内容:

BkUpSalesReportJan2011(txt).zip
BkUpSalesReportJan2011(pdf).zip
BkUpSalesReportJan2011(doc).zip
BkUpSalesReportFeb2011(txt).zip
BkUpSalesReportMar2011(doc).zip
BkUpSalesReportMar2011(pdf).zip
Goes on for a few hundred more files...

我想根据文件类型(按优先级顺序)保存每个报告的一个副本。我想保留PDF并删除所有重复项。如果没有PDF,则保留DOC并最后保留TXT。

使用Visual C#和Windows窗体实现排序和删除的最佳方法是什么?

1 个答案:

答案 0 :(得分:3)

您可以使用Regex解析数据的文件名,使用Linq获取Duplicates或Distinct记录。

POCO:

public class FileData
{
    public string Original { get; set; }
    public string Type { get; set; }
    public string Name { get; set; }

    public int Weight { get { return GetWeight(Type); } }

    private static int GetWeight(string option)
    {
        // This will put the files in order by pdf, doc, txt, etc
        switch(option)
        {
            case "pdf":
                return 0;
            case "doc":
                return 1;
            case "txt":
                return 2;
            default:
                return 3;
        }
    }
}

您需要一个权重函数,因为默认的OrderBy将按字母顺序排列。这样,您可以指定哪些文件具有更重要的意义。

代码:

// you can substitute this with Directory.GetFiles
// e.g. var files = Directory.GetFiles("Path/To/Files");
var files = new []
{
    "BkUpSalesReportJan2011(txt).zip",
    "BkUpSalesReportJan2011(pdf).zip",
    "BkUpSalesReportJan2011(doc).zip",
    "BkUpSalesReportFeb2011(txt).zip",
    "BkUpSalesReportMar2011(doc).zip",
    "BkUpSalesReportMar2011(pdf).zip"
};

var pattern = @"(?<FileName>.+)\((?<FileType>\w+)\)\.zip";
// (?<FileName>.+) Match the first part in a named group
// \( Match the first open parenthesis
// (?<FileType>\w+) Match the txt/pdf/doc/whatever in a named group
// \) Match the closing parenthesis
// \.zip Match a period followed by the zip

var matchedFiles = files.Select(f => Regex.Match(f, pattern))
                        .Where(m => m.Success)
                        .Select(f =>
                            new FileData
                                {
                                    Type = f.Groups["FileType"].Value,
                                    Name = f.Groups["FileName"].Value,
                                    Original = f.Value
                                }
                               ).ToList();

// Group all the files by the name e.g. BkUpSalesReportJan2011
// Transform the group into order and take the first record
// Take the original file name to get the originals
var distinct = matchedFiles.GroupBy(f => f.Name)
                           .Select(g => g.OrderBy(f => f.Weight).First())
                           .Select(f => f.Original);

// Group all the files by the name e.g. BkUpSalesReportJan2011
// Transform the group into order and skip the first record
// Since the records are still in a nested IEnumerable we need to flatten it
// Take the original file name to get the duplicates
var duplicates = matchedFiles.GroupBy(f => f.Name)
                             .Select(g => g.OrderBy(f => f.Weight).Skip(1))
                             .SelectMany(g => g)
                             .Select(f => f.Original);

另见:

Directory.GetFiles