Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

Add folder, unable to decompress

Đang mở
#883 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
25/100
Loại issue
Lỗi
Độ rõ ràng
Cần làm rõ
Mức độ hoạt động
Đình trệ
Công nghệ
csharp
Lĩnh vực
backend

Hướng nghiên cứu

Bắt đầu bằng cách rút gọn các phương thức C# Compress và Decomparess được cung cấp thành một bản tái hiện tối thiểu bằng SharpZipLib 1.3.3, tập trung vào các lệnh gọi ZipOutputStream và ZipInputStream liên quan đến các mục thư mục. Xác nhận chính xác nội dung của tệp lưu trữ và thao tác tạo ra “Stored, but compressed != uncompressed”; được xem là hoàn tất khi có lỗi có thể tái hiện và hành vi đã được xác minh đối với việc thêm và giải nén các thư mục.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

bug zip
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

Ngôn ngữ chính
C#
Star
3.9k
Fork
1k
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của icsharpcode/SharpZipLib

Tất cả issue của icsharpcode/SharpZipLib

Issue tương tự

Thêm issue về C#

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.