You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#如何从ZipArchive中获取各文件前缀对应的最新文件

从ZipArchive压缩包提取各文件标识前缀对应最新版本文件

需求说明

文件命名规则

压缩包内文件名下划线_分隔为4段:

  • 第一段:文件标识前缀,例如file1、file2
  • 第二段:创建日期
  • 第三段:修改日期
  • 第四段:创建时间,格式为HH-mm-ss

示例场景

压缩包内包含3个文件:

  • file1_2022-06-20_2022-06-20_10-20-32
  • file1_2022-06-20_2022-06-20_10-30-50
  • file2_2022-06-20_2022-06-20_14-10-20
    预期返回每个前缀下时间最新的文件,即结果应为:

file1_2022-06-20_2022-06-20_10-30-50
file2_2022-06-20_2022-06-20_14-10-20

原有代码问题

原有实现仅对匹配的文件按LastWriteTime做全局倒序,没有按前缀分组逻辑,会返回全部3个匹配文件,无法满足分组取最新的要求,原有代码如下:

private void FindMostRecentFilesFromZip(string zipPath, string destPath)
{
    using (var zipArchive = ZipFile.Open(zipPath, ZipArchiveMode.Read))
    {
        var matchesFiles = new List<ZipArchiveEntry>();

        foreach (var entry in zipArchive.Entries)
        {
            if (entry.Name.StartsWith(pattern))
            {
                matchesFiles .Add(entry);
            }
        }
        // how to get only the most recent files here???
        var mostRecentFiles = matchesFiles.OrderByDescending(f => f.LastWriteTime);
        
        //here all three files are returned, while the result should only contains two files as explained above
    }
}

修正后实现

using System.Globalization;
using System.IO.Compression;
using System.Linq;

private void FindMostRecentFilesFromZip(string zipPath, string destPath, string matchPattern)
{
    using (var zipArchive = ZipFile.Open(zipPath, ZipArchiveMode.Read))
    {
        var mostRecentFiles = zipArchive.Entries
            // 过滤符合匹配规则的文件,跳过目录条目
            .Where(entry => !entry.FullName.EndsWith('/') && entry.Name.StartsWith(matchPattern))
            // 按文件标识前缀分组
            .GroupBy(entry => entry.Name.Split('_')[0])
            // 每组取时间最新的1个文件
            .Select(group => group
                .OrderByDescending(entry =>
                {
                    // 优先用文件名内嵌的时间排序,避免zip元数据时间不准
                    var nameParts = entry.Name.Split('_');
                    if (nameParts.Length >= 4
                        && DateTime.TryParseExact(
                            $"{nameParts[1]}_{nameParts[3]}",
                            "yyyy-MM-dd_HH-mm-ss",
                            CultureInfo.InvariantCulture,
                            DateTimeStyles.None,
                            out var embedTime))
                    {
                        return embedTime;
                    }
                    // 文件名时间解析失败时回退用zip条目自带的最后修改时间
                    return entry.LastWriteTime.DateTime;
                })
                .First())
            .ToList();

        // 解压最新文件到目标目录
        foreach (var fileEntry in mostRecentFiles)
        {
            fileEntry.ExtractToFile(Path.Combine(destPath, fileEntry.Name), overwrite: true);
        }
    }
}

关键逻辑说明

  • 增加目录条目过滤,避免把zip内的文件夹当成文件处理
  • 严格对齐文件名规则,取第一个下划线前的内容作为分组依据
  • 排序优先级使用文件名内嵌的时间戳,规避压缩包元数据时间和实际文件版本不一致的问题,解析失败自动降级用zip自带的时间属性
  • 每个分组取倒序排序后的第一条,即为对应前缀下的最新版本文件,示例场景下会正确返回2个目标文件

内容的提问来源于stack exchange,提问作者L.Cam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 20:36:20