-
Notifications
You must be signed in to change notification settings - Fork 993
Description
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;
/// <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”
Expected behavior
Fix the bug。
Operating System
Windows
Framework Version
.NET Framework 4.x
Tags
ZIP
Additional context
No response