網(wǎng)站首頁 編程語言 正文
一、起因
由于公司開發(fā)項(xiàng)目需要遷移部署到Linux環(huán)境部署運(yùn)行,之前項(xiàng)目中生成Zip壓縮文件的代碼邏輯在Linux運(yùn)行生成壓縮文件不正常。
本篇記錄文件排查處理過程。
二、問題現(xiàn)象
- 壓縮文件生成目錄不正確,文件目錄為:\root\ziptest\upgrade\_dsconnCfg.txt(項(xiàng)目部署目錄)
- 壓縮文件數(shù)量不正確
- 壓縮文件最后修改時間不匹配
待壓縮文件:
壓縮結(jié)果:
三、解決過程:
1、原始實(shí)現(xiàn)壓縮的主要邏輯:
using System.IO.Compression; using System.IO; ////// 文件壓縮類 /// public class ZipHelper { ////// 單文件壓縮成ZIP /// /// 源文件路徑 /// ZIP文件路徑 /// ZIP文件名 ///public static bool SimpleFileZip(string fileSource, string fileOut, string 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; } /// /// 多文件壓縮成ZIP /// /// 源文件路徑 /// ZIP文件路徑 /// ZIP文件名 ///public static bool FilesZip(List 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); //設(shè)置文件最后修改時間 readMeEntry.LastWriteTime = File.GetLastWriteTime(fileSource); using (Stream stream = readMeEntry.Open()) { byte[] bytes = File.ReadAllBytes(fileSource); stream.Write(bytes, 0, bytes.Length); } } }
2、生成路徑不正確問題:通過對代碼檢測發(fā)現(xiàn),在代碼中處理邏輯對目錄路徑替換處理時:使用了"\\";導(dǎo)致在Linux代碼無效。修改對于代碼為以下內(nèi)容:
////// 多文件壓縮成ZIP /// /// 源文件路徑 /// ZIP文件路徑 /// ZIP文件名 ///public static bool FilesZip(List 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、排查生成文件數(shù)量異常問題,輸出異常信息。
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:\coding\ZlsoftClientService\zlWebPluginsUpgradeServer\UpgradeMode\ZipHelper.cs:line 84
? ?at zlWebPluginsUpgradeServer.Upgrade.ZipHelper.FilesZip(List`1 fileSources, String fileOut) in F:\coding\ZlsoftClientService\zlWebPluginsUpgradeServer\UpgradeMode\ZipHelper.cs:line 62
發(fā)現(xiàn)因?yàn)樯蓧嚎s文件后設(shè)置最后修改時間異常,導(dǎo)致生成壓縮文件數(shù)量不正確;且最后修改時間不匹配。
4、根據(jù)日志,調(diào)整
using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Update))
到此以上在Linux中生成壓縮文件問題都已解決。
四、總結(jié):
1、代碼中路徑操作,不要使用固定字符串;應(yīng)該使用Path類提供的相關(guān)字段、方法操作
2、設(shè)置壓縮項(xiàng)屬性時,需要使用Update模式。
最后放上壓縮幫助類:
////// 文件壓縮類 /// public class ZipHelper { ////// 單文件壓縮成ZIP /// /// 源文件路徑 /// ZIP文件路徑 /// ZIP文件名:相對路徑 ///public static void SimpleFileZip(string fileSource, string fileOut, string fileName) { using (FileStream zipFileToOpen = new FileStream(fileOut, FileMode.OpenOrCreate)) { using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Update)) { fileName = fileName.Trim(Path.DirectorySeparatorChar); ZipFile(fileSource, fileName, archive); } } } /// /// 多文件壓縮成ZIP /// /// 源文件路徑 /// ZIP文件路徑 /// ZIP文件名 ///public static void FilesZip(List fileSources, string fileOut) { 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); } } } } /// /// 壓縮指定文件夾 /// /// /// public static void DirectoryZip(string sourceDirectory, string fileOut) { string[] allFiles = Directory.GetFiles(sourceDirectory, "", SearchOption.AllDirectories); using (FileStream zipFileToOpen = new FileStream(fileOut, FileMode.OpenOrCreate)) { using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Update)) { foreach (var file in allFiles) { //獲取壓縮文件相對目錄 string fileName = file.Replace(sourceDirectory + Path.DirectorySeparatorChar, ""); ZipFile(file, fileName, archive); } } } } ////// 解壓文件到指定目錄 /// /// /// public static void UnZip(string upZipDirPath, string zipPath) { if (!Directory.Exists(upZipDirPath)) Directory.CreateDirectory(upZipDirPath); using (FileStream zipFileToOpen = new FileStream(zipPath, FileMode.Open)) { using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Read)) { archive.ExtractToDirectory(upZipDirPath); } } } ////// 生成壓縮文件 /// /// 源文件 /// 壓縮文件相對目錄 /// 壓縮文件包 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); } } }
原文鏈接:https://www.cnblogs.com/cwsheng/p/15943183.html
相關(guān)推薦
- 2023-02-27 python定時任務(wù)sched庫用法簡單實(shí)例_python
- 2022-10-02 Selenium+Python自動化測試入門_python
- 2022-06-12 C語言數(shù)學(xué)問題與簡單DP01背包問題詳解_C 語言
- 2022-06-08 淺談C#多線程下的調(diào)優(yōu)_C#教程
- 2022-08-29 Python常見異常處理總結(jié)_python
- 2022-06-20 音視頻基本概念和FFmpeg的簡單入門教程詳解_相關(guān)技巧
- 2023-04-24 numpy.reshape()的函數(shù)的具體使用_python
- 2022-10-06 C#中?MessageBox的使用技巧_C 語言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支