Open Luohui109 opened 1 week ago
Version SharpZipLib. 1.3.3 I'm not sure that version 4 has this issue “Stored, but compressed != uncompressed”
No response
Step 1: namespace SoluM.Utils.Zip { using ICSharpCode.SharpZipLib.Zip; using System.Collections; using System.IO; using System.Threading;
/// <summary> /// ICSharpCode.SharpZipLib.Zip /// </summary> public class ZipHelper { private const int BufferSize = 1024; public const int CompressionLevelMin = 0; public const int CompressionLevelMax = 9; internal static int CheckCompressionLevel(int compressionlevel) { return compressionlevel < CompressionLevelMin ? CompressionLevelMin : compressionlevel > CompressionLevelMax ? CompressionLevelMax : compressionlevel; } public class FileEntry { /// <summary> /// /// </summary> public string Name { get; set; } /// <summary> /// /// </summary> public string FullName { get; set; } /// <summary> /// /// </summary> public string ZipEntryName { get; set; } /// <summary> /// /// </summary> public bool IsDirectory { get; set; } /// <summary> /// /// </summary> public string Extension { get; set; } /// <summary> /// /// </summary> public long Length { get; set; } /// <summary> /// /// </summary> public bool ReadOnly { get; set; } /// <summary> /// /// </summary> public FileAttributes Attributes { get; set; } /// <summary> /// /// </summary> public DateTime CreationTime { get; set; } /// <summary> /// /// </summary> public DateTime LastAccessTime { get; set; } /// <summary> /// /// </summary> public DateTime LastWriteTime { get; set; } }
public static bool IsDiskOnly(string path) { bool result = false;
if (!string.IsNullOrWhiteSpace(path) && (File.Exists(path) || Directory.Exists(path))) { DirectoryInfo directoryInfo = new DirectoryInfo(path); result = directoryInfo.Root.FullName == directoryInfo.FullName; } return result; } public static bool HasDescendants(string path) { bool result = false; if (!string.IsNullOrWhiteSpace(path) && (File.Exists(path) || Directory.Exists(path))) { if (File.Exists(path)) { result = true; } else if (Directory.Exists(path)) { result = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories).Length > 0; } } return result; } public static List<FileEntry> GetFileEntry(string path, bool includedemptydir = true) { List<FileEntry> fileEntryList = new List<FileEntry>(); FileEntry fileEntry; FileInfo fileInfo; DirectoryInfo directoryInfo; // if (!string.IsNullOrWhiteSpace(path)) { // if (path.EndsWith(@"\")) { path = path.Remove(path.LastIndexOf(@"\")); } if (File.Exists(path)) { fileInfo = new FileInfo(path); fileEntry = new FileEntry(); fileEntry.Name = fileInfo.Name; fileEntry.FullName = fileInfo.FullName; fileEntry.ZipEntryName = fileInfo.Name; fileEntry.IsDirectory = false; fileEntry.Extension = fileInfo.Extension; fileEntry.Length = fileInfo.Length; fileEntry.ReadOnly = fileInfo.IsReadOnly; fileEntry.Attributes = fileInfo.Attributes; fileEntry.CreationTime = fileInfo.CreationTime; fileEntry.LastAccessTime = fileInfo.LastAccessTime; fileEntry.LastWriteTime = fileInfo.LastWriteTime; fileEntryList.Add(fileEntry); } else if (Directory.Exists(path)) { if (!IsDiskOnly(path)) { if (includedemptydir || HasDescendants(path)) { string parentPath = Path.GetDirectoryName(path) + @"\"; if (parentPath.EndsWith(@":\\")) { parentPath = parentPath.Replace(@"\\", @"\"); } //先将顶级文件夹压入 directoryInfo = new DirectoryInfo(path); fileEntry = new FileEntry(); fileEntry.Name = directoryInfo.Name; fileEntry.FullName = directoryInfo.FullName; fileEntry.ZipEntryName = directoryInfo.FullName.Replace(parentPath, ""); fileEntry.IsDirectory = true; fileEntry.Extension = ""; fileEntry.Length = 0; fileEntry.ReadOnly = default; fileEntry.Attributes = directoryInfo.Attributes; fileEntry.CreationTime = directoryInfo.CreationTime; fileEntry.LastAccessTime = directoryInfo.LastAccessTime; fileEntry.LastWriteTime = directoryInfo.LastWriteTime; fileEntryList.Add(fileEntry); // string[] directories = Directory.GetDirectories(path, "*.*", SearchOption.AllDirectories); foreach (string dir in directories) { if (includedemptydir || HasDescendants(dir)) { directoryInfo = new DirectoryInfo(dir); fileEntry = new FileEntry(); fileEntry.Name = directoryInfo.Name; fileEntry.FullName = directoryInfo.FullName; fileEntry.ZipEntryName = directoryInfo.FullName.Replace(parentPath, ""); fileEntry.IsDirectory = true; fileEntry.Extension = ""; fileEntry.Length = 0; fileEntry.ReadOnly = default; fileEntry.Attributes = directoryInfo.Attributes; fileEntry.CreationTime = directoryInfo.CreationTime; fileEntry.LastAccessTime = directoryInfo.LastAccessTime; fileEntry.LastWriteTime = directoryInfo.LastWriteTime; fileEntryList.Add(fileEntry); } } // string[] files = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories); foreach (string file in files) { fileInfo = new FileInfo(file); fileEntry = new FileEntry(); fileEntry.Name = fileInfo.Name; fileEntry.FullName = fileInfo.FullName; fileEntry.ZipEntryName = fileInfo.FullName.Replace(parentPath, ""); fileEntry.IsDirectory = false; fileEntry.Extension = fileInfo.Extension; fileEntry.Length = fileInfo.Length; fileEntry.ReadOnly = fileInfo.IsReadOnly; fileEntry.Attributes = fileInfo.Attributes; fileEntry.CreationTime = fileInfo.CreationTime; fileEntry.LastAccessTime = fileInfo.LastAccessTime; fileEntry.LastWriteTime = fileInfo.LastWriteTime; fileEntryList.Add(fileEntry); } } } } } return fileEntryList; } public static List<FileEntry> GetFileEntry(IEnumerable<string> pathlist, bool includedemptydir = true) { List<FileEntry> fileEntryList = new List<FileEntry>(); foreach (string path in pathlist) { fileEntryList.AddRange(GetFileEntry(path)); } return fileEntryList; } public static string Compress(IEnumerable<string> sourcepathlist, string zipfilepath = null, string comment = null, string password = null, int compressionlevel = 6) { string result = null; try { // if (sourcepathlist == null || !(sourcepathlist.Count() > 0)) { throw new Exception("待添加到压缩包的全路径文件或文件夹列表不能为空、NULL或空白字符!"); } // foreach (string sourcepath in sourcepathlist) { if (string.IsNullOrWhiteSpace(sourcepath)) { throw new Exception("待添加到压缩包的全路径文件或文件夹列表中的元素不能为空、NULL或空白字符!"); } if (!(File.Exists(sourcepath) || Directory.Exists(sourcepath))) { throw new Exception($"待添加到压缩包的全路径文件或文件夹列表中元素[{sourcepath}]在存储设备上不存在!"); } } //获取文件、文件夹列表 List<FileEntry> fileEntryList = GetFileEntry(sourcepathlist); //检测目标文件夹是否存在,如果不存在则建立 string zipFileDirectory = Path.GetDirectoryName(zipfilepath); if (!Directory.Exists(zipFileDirectory)) { Directory.CreateDirectory(zipFileDirectory); } //创建压缩文件,若存在则覆盖 using (FileStream zipStream = File.Create(zipfilepath)) { using (ZipOutputStream zipOutputStream = new ZipOutputStream(zipStream)) { zipOutputStream.Password = password;//设置密码 zipOutputStream.SetComment(comment);//添加注释 zipOutputStream.SetLevel(CheckCompressionLevel(compressionlevel));//设置压缩等级 foreach (FileEntry fileEntry in fileEntryList)//从List取文件添加到压缩文件 { if (fileEntry.IsDirectory) { ZipEntry zipEntry = new ZipEntry(fileEntry.ZipEntryName + @"/"); zipOutputStream.PutNextEntry(zipEntry); } else { using (FileStream fileStream = File.OpenRead(fileEntry.FullName)) { ZipEntry zipEntry = new ZipEntry(fileEntry.ZipEntryName); zipEntry.DateTime = fileEntry.LastWriteTime; zipEntry.Size = fileEntry.Length; zipOutputStream.PutNextEntry(zipEntry); byte[] buffer = new byte[BufferSize]; int read = 0; while ((read = fileStream.Read(buffer, 0, BufferSize)) > 0) { zipOutputStream.Write(buffer, 0, read); } } } } // zipOutputStream.Flush(); } } // result = zipfilepath; } catch (System.Exception ex) { if (File.Exists(zipfilepath)) { File.Delete(zipfilepath); } throw new Exception("压缩失败!", ex); } return result; } public static string Decomparess(string zipfilepath, string destinationdirectory = null, string password = null) { string result = null; // if (string.IsNullOrWhiteSpace(zipfilepath)) { throw new Exception("待解压缩文件[{zipfilepath}]不能为空、NULL或空白字符!"); } // if (!File.Exists(zipfilepath)) { throw new FileNotFoundException($"待解压缩文件[{zipfilepath}]在存储设备上不存在!"); } // FileInfo fileInfo = new FileInfo(zipfilepath); string directory = fileInfo.DirectoryName + @"\"; string filename = fileInfo.Name.Substring(0, fileInfo.Name.Length - fileInfo.Extension.Length); // if (string.IsNullOrWhiteSpace(destinationdirectory)) { destinationdirectory = directory + filename + @"\"; } else{ destinationdirectory = destinationdirectory + (destinationdirectory.EndsWith(@"\") ? "" : @"\") + filename + @"\"; if (!Directory.Exists(destinationdirectory)) { Directory.CreateDirectory(destinationdirectory); }} try { // if (!Directory.Exists(destinationdirectory)) { Directory.CreateDirectory(destinationdirectory); } // using (FileStream zipFileStream = File.OpenRead(zipfilepath)) { using (ZipInputStream zipInputStream = new ZipInputStream(zipFileStream)) { zipInputStream.Password = password; ZipEntry zipEntry; while ((zipEntry = zipInputStream.GetNextEntry()) != null) { //如果是文件夹则创建 if (zipEntry.IsDirectory) { Directory.CreateDirectory(Path.Combine(destinationdirectory, Path.GetDirectoryName(zipEntry.Name))); } //如果是文件则创建 else { string fileName = Path.GetFileName(zipEntry.Name); if (!string.IsNullOrEmpty(fileName) && fileName.Trim().Length > 0) { FileInfo fileInfo = new FileInfo(Path.Combine(destinationdirectory, zipEntry.Name)); using (FileStream fileStream = fileInfo.Create()) { byte[] buffer = new byte[BufferSize]; int read = 0; while ((read = zipInputStream.Read(buffer, 0, BufferSize)) > 0) { fileStream.Write(buffer, 0, read); } // fileStream.Flush(); } // fileInfo.LastWriteTime = zipEntry.DateTime; } } } } } // result = destinationdirectory; } catch (System.Exception ex) { if (Directory.Exists(destinationdirectory)) { Directory.Delete(destinationdirectory, true); } throw new Exception("解压缩发生错误!", ex); } return result; } public static string CompressAdd(string zipfilepath, IEnumerable<string> sourcepathlist, string zipdirpath = null, string password = null) { string result = null; try { // if (string.IsNullOrWhiteSpace(zipfilepath)) { throw new Exception("压缩文件[{zipfilepath}]不能为空、NULL或空白字符!"); } // if (!File.Exists(zipfilepath)) { throw new FileNotFoundException($"压缩文件[{zipfilepath}]在存储设备上不存在!"); } // if (sourcepathlist == null || !(sourcepathlist.Count() > 0)) { throw new Exception("待添加到压缩包的全路径文件或文件夹列表不能为空、NULL或空白字符!"); } // foreach (string sourcepath in sourcepathlist) { if (string.IsNullOrWhiteSpace(sourcepath)) { throw new Exception("待添加到压缩包的全路径文件或文件夹列表中的元素不能为空、NULL或空白字符!"); } if (!(File.Exists(sourcepath) || Directory.Exists(sourcepath))) { throw new Exception($"待添加到压缩包的全路径文件或文件夹列表中元素[{sourcepath}]在存储设备上不存在!"); } } // if (string.IsNullOrWhiteSpace(zipdirpath)) { zipdirpath = null; } else { if (!zipdirpath.EndsWith(@"/")) { zipdirpath = zipdirpath + @"/"; } } //获取文件、文件夹列表 List<FileEntry> fileEntryList = GetFileEntry(sourcepathlist); //将文件添加到已有zip文件中 using (ZipFile zip = new ZipFile(zipfilepath)) { //当前添加文件的密码,一个ZIP中,不同文件可以设置不同的密码 //zip.Password = password; //更新压缩档的注释(全局) //zip.SetComment("1"); zip.BeginUpdate(); foreach (FileEntry fileEntry in fileEntryList) { if (fileEntry.IsDirectory) { //zip.Add(new ZipEntry((zipdirpath != null ? zipdirpath : "") + fileEntry.ZipEntryName + @"/") { Size = 0, CompressedSize = 0, CompressionMethod = CompressionMethod.Deflated }); zip.AddDirectory((zipdirpath != null ? zipdirpath : "") + fileEntry.ZipEntryName + @"/"); } else { //zip.Add(fileEntry.FullName, (zipdirpath != null ? zipdirpath : "") + fileEntry.ZipEntryName); zip.Add(new StaticDataSource(fileEntry.FullName), new ZipEntry((zipdirpath != null ? zipdirpath : "") + fileEntry.ZipEntryName) { DateTime = fileEntry.LastWriteTime, Size = fileEntry.Length, CompressionMethod = CompressionMethod.Deflated }); } } zip.CommitUpdate(); } // result = zipfilepath; } catch (System.Exception ex) { throw new Exception("压缩包添加文件失败!", ex); } return result; } }
}
string[] filepaths = new string[] { @"C:\bill\d0d76d40-617b-496a-81e5-3105eae7b723.jpg", @"C:\bill\caf4e9b1-0232-4f0e-bf57-d31396ea73e9.jpg", @"C:\bill\tttt", @"C:\ball" };
Step 2: string zip = SoluM.Utils.Zip.ZipHelper.Compress(filepaths, null, "11111111111111", "123456"); Process.Start("explorer.exe", "/select, " + zip); string dezip = SoluM.Utils.Zip.ZipHelper.Decomparess(zip, @"C:\zipDe", "123456");
Step 3: string zip2 = SoluM.Utils.Zip.ZipHelper.CompressAdd(zippath3, new string[] { @"C:\bill\培训签到1.jpg", @"C:\bill\培训签到2.jpg", @"C:\bill\培训签到3.jpg", @"C:\HP_LaserJet_Pro_MFP_M426-M427" }, @"ball/1/2/", null);
Step 4: SoluM.Utils.Zip.ZipHelper.Decomparess(zip2, null, "123456"); --Here,while ((zipEntry = zipInputStream.GetNextEntry()) != null),throw “Stored, but compressed != uncompressed”
Fix the bug。
Windows
.NET Framework 4.x
ZIP
这是来自QQ邮箱的假期自动回复邮件。 您好,我最近正在休假中,无法亲自回复您的邮件。我将在假期结束后,尽快给您回复。
Describe the bug
Version SharpZipLib. 1.3.3 I'm not sure that version 4 has this issue “Stored, but compressed != uncompressed”
Reproduction Code
No response
Steps to reproduce
Step 1: namespace SoluM.Utils.Zip { using ICSharpCode.SharpZipLib.Zip; using System.Collections; using System.IO; using System.Threading;
public static bool IsDiskOnly(string path) { bool result = false;
}
string[] filepaths = new string[] { @"C:\bill\d0d76d40-617b-496a-81e5-3105eae7b723.jpg", @"C:\bill\caf4e9b1-0232-4f0e-bf57-d31396ea73e9.jpg", @"C:\bill\tttt", @"C:\ball" };
Step 2: string zip = SoluM.Utils.Zip.ZipHelper.Compress(filepaths, null, "11111111111111", "123456"); Process.Start("explorer.exe", "/select, " + zip); string dezip = SoluM.Utils.Zip.ZipHelper.Decomparess(zip, @"C:\zipDe", "123456");
Step 3: string zip2 = SoluM.Utils.Zip.ZipHelper.CompressAdd(zippath3, new string[] { @"C:\bill\培训签到1.jpg", @"C:\bill\培训签到2.jpg", @"C:\bill\培训签到3.jpg", @"C:\HP_LaserJet_Pro_MFP_M426-M427" }, @"ball/1/2/", null);
Step 4: SoluM.Utils.Zip.ZipHelper.Decomparess(zip2, null, "123456"); --Here,while ((zipEntry = zipInputStream.GetNextEntry()) != null),throw “Stored, but compressed != uncompressed”
Expected behavior
Fix the bug。
Operating System
Windows
Framework Version
.NET Framework 4.x
Tags
ZIP
Additional context
No response