.Net 生成压缩文件问题记录(推荐)

2022-04-17 06:20:50
目录
一、起因二、问题现象三、解决过程:四、总结:

一、起因

 由于公司开发项目需要迁移部署到linux环境部署运行,之前项目中生成Zip压缩文件的代码逻辑在Linux运行生成压缩文件不正常。

 本篇记录文件排查处理过程。

二、问题现象

压缩文件生成目录不正确,文件目录为:rootziptestupgrade_dsconnCfg.txt(项目部署目录)压缩文件数量不正确压缩文件最后修改时间不匹配

 待压缩文件:

  

.Net生成压缩文件问题记录(推荐)

 压缩结果:

.Net生成压缩文件问题记录(推荐)

三、解决过程:

 1、原始实现压缩的主要逻辑:

using System.IO.Compression;using System.IO;/// <summary>/// 文件压缩类/// </summary>public class ZipHelper{    /// <summary>    /// 单文件压缩成ZIP    /// </summary>    /// <param name="fileSource">源文件路径</param>    /// <param name="fileOut">ZIP文件路径</param>    /// <param name="fileName">ZIP文件名</param>    /// <returns></returns>    public static bool SimpleFileZip(string fileSource, string fileOut, strwww.easck.coming fileName)    {        try        {            using (FileStream zipFileToOpen = new FileStream(fileOut, FileMode.Create))            {                using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Create))                {                    ZipFile(fileSource, fileName, archive);                }            }        }        catch        {            return false;        }        return true;    }    /// <summary>    /// 多文件压缩成ZIP    /// </summary>    /// <param name="fileSource">源文件路径</param>    /// <param name="fileOut">ZIP文件路径</param>    /// <param name="fileName">ZIP文件名</param>    /// <returns></returns>    public static bool FilesZip(List<string> fileSources, string fileOut)    {        try        {            using (FileStream zipFileToOpen = new FileStream(fileOut, FileMode.Create))            {                using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Create))                {                    foreach (var file in fileSources)                    {               //计算相对路径                        string fileName = file.Replace(AppConsts.ServerUpdateFile + "\", "");                        ZipFile(file, fileName, archive);                    }                }            }        }        catch        {            return false;        }        return true;    }    private static void ZipFile(string fileSource, string fileName, ZipArchive archive)    {        ZipArchiveEntry readMeEntry = archive.CreateEntry(fileName);     //设置文件最后修改时间        readMeEntry.LastWriteTime = File.GetLastWriteTime(fileSource);        using (Stream stream = readMeEntry.Open())        {            byte[] bytes = File.ReadAllBytes(fileSource);            stream.Write(bytes, 0, bytes.Length);        }    }}

 2、生成路径不正确问题:通过对代码检测发现,在代码中处理逻辑对目录路径替换处理时:使用了"\";导致在Linux代码无效。修改对于代码为以下内容:

/// <summary>/// 多文件压缩成ZIP/// </summary>/// <param name="fileSource">源文件路径</param>/// <param name="fileOut">ZIP文件路径</param>/// <param name="fileName">ZIP文件名</param>/// <returns></returns>public static bool FilesZip(List<string> fileSources, string fileOut){    try    {        using (FileStream zipFileToOpen = new FileStream(fileOut, FileMode.OpenOrCreate))        {            using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Update))            {                foreach (var file in fileSources)                {            //计算压缩文件相对路径:目录/文件名                    string fileName = file.Replace(AppConsts.ServerUpdateFile + Path.DirectorySeparatorChar, "");                    ZipFile(file, fileName, archive);                }            }        }    }    catch (Exception ex)    {        Console.WriteLine($"ERROR:{ex}");        return false;    }    return true;}

 3、排查生成文件数量异常问题,输出异常信息。

ERROR:Cannot modify entry in Create mode after entry has been opened for writing.
   at System.IO.Compression.ZipArchiveEntry.set_LastWriteTime(DateTimeOffset value)
   at zlWebPluginsUpgradeServer.Upgrade.ZipHelper.ZipFile(String fileSource, String fileName, ZipArchive archive) in F:codingZlsoftClientServicezlWebPluginsUpgradeServerUpgradeModeZipHelper.cs:line 84
   at zlWebPluginsUpgradeServer.Upgrade.ZipHelper.FilesZip(List`1 fileSources, String fileOut) in F:codingZlsoftClientServicezlWebPluginsUpgradeServerUpgradeModeZipHelper.cs:line 62

  发现因为生成压缩文件后设置最后修改时间异常,导致生成压缩文件数量不正确;且最后修改时间不匹配。

 4、根据日志,调整

using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Update))