Có ai biết cách tốt để nén hoặc giải nén các tập tin và thư mục trong C# nhanh chóng không? Xử lý các tệp lớn có thể là cần thiết.Nén/giải nén các thư mục & tập tin
Trả lời
Kể từ .Net 1.1, phương thức khả dụng duy nhất là tiếp cận các thư viện java.
Using the Zip Classes in the J# Class Libraries to Compress Files and Data with C#
Không chắc chắn điều này có thay đổi trong các phiên bản gần đây hay không.
Tôi đã luôn sử dụng Thư viện SharpZip.
Bạn có thể sử dụng một 3rd-party library such as SharpZip như Tom chỉ ra.
Một cách khác (không đi bên thứ ba) là sử dụng API Windows Shell. Bạn sẽ cần đặt tham chiếu đến thư viện Microsoft Shell Controls và Automation COM trong dự án C# của bạn. Gerald Gibson có một ví dụ tại địa chỉ:
http://geraldgibson.net/dnn/Home/CZipFileCompression/tabid/148/Default.aspx
này là rất dễ dàng để làm trong java, và như đã nói ở trên, bạn có thể đạt được vào thư viện java.util.zip từ C#. Đối với tài liệu tham khảo xem:
java.util.zip javadocs
sample code
Tôi sử dụng này một thời gian trước đây để làm một (recursive) zip sâu sắc về một cấu trúc thư mục, nhưng tôi không nghĩ rằng tôi đã từng sử dụng giải nén. Nếu tôi có động lực như vậy, tôi có thể rút mã đó ra và chỉnh sửa nó vào đây sau.
Không gian tên khung công tác .Net 2.0 System.IO.Compression
hỗ trợ thuật toán GZip và Deflate. Dưới đây là hai phương pháp nén và giải nén luồng byte mà bạn có thể lấy từ đối tượng tệp của mình. Bạn có thể thuê GZipStream
cho DefaultStream
trong các phương pháp bên dưới để sử dụng thuật toán đó. Điều này vẫn còn vấn đề xử lý các tập tin nén với các thuật toán khác nhau mặc dù.
public static byte[] Compress(byte[] data)
{
MemoryStream output = new MemoryStream();
GZipStream gzip = new GZipStream(output, CompressionMode.Compress, true);
gzip.Write(data, 0, data.Length);
gzip.Close();
return output.ToArray();
}
public static byte[] Decompress(byte[] data)
{
MemoryStream input = new MemoryStream();
input.Write(data, 0, data.Length);
input.Position = 0;
GZipStream gzip = new GZipStream(input, CompressionMode.Decompress, true);
MemoryStream output = new MemoryStream();
byte[] buff = new byte[64];
int read = -1;
read = gzip.Read(buff, 0, buff.Length);
while (read > 0)
{
output.Write(buff, 0, read);
read = gzip.Read(buff, 0, buff.Length);
}
gzip.Close();
return output.ToArray();
}
Một lựa chọn tốt khác cũng là DotNetZip.
GZipStream là một tiện ích thực sự tốt để sử dụng.
Câu trả lời của tôi sẽ nhắm mắt lại và chọn DotNetZip. Nó đã được thử nghiệm bởi một cộng đồng lớn.
bạn có thể tạo file zip với phương pháp này:
public async Task<string> CreateZipFile(string sourceDirectoryPath, string name)
{
var path = HostingEnvironment.MapPath(TempPath) + name;
await Task.Run(() =>
{
if (File.Exists(path)) File.Delete(path);
ZipFile.CreateFromDirectory(sourceDirectoryPath, path);
});
return path;
}
và sau đó bạn có thể giải nén file zip với các phương pháp này:
1- phương pháp này làm việc với đường dẫn tập tin zip
public async Task ExtractZipFile(string filePath, string destinationDirectoryName)
{
await Task.Run(() =>
{
var archive = ZipFile.Open(filePath, ZipArchiveMode.Read);
foreach (var entry in archive.Entries)
{
entry.ExtractToFile(Path.Combine(destinationDirectoryName, entry.FullName), true);
}
archive.Dispose();
});
}
2 - phương pháp này hoạt động với luồng tệp zip
public async Task ExtractZipFile(Stream zipFile, string destinationDirectoryName)
{
string filePath = HostingEnvironment.MapPath(TempPath) + Utility.GetRandomNumber(1, int.MaxValue);
using (FileStream output = new FileStream(filePath, FileMode.Create))
{
await zipFile.CopyToAsync(output);
}
await Task.Run(() => ZipFile.ExtractToDirectory(filePath, destinationDirectoryName));
await Task.Run(() => File.Delete(filePath));
}
Lưu ý: Tôi đã tìm thấy * int dòng chảy * lỗi trong mã SharpZip năm trước, khiến nó thất bại trên các tệp ngẫu nhiên vừa xảy ra để có kết hợp các giá trị đúng. Không chắc chắn nếu điều đó đã được cố định, nhưng từ bộ nhớ tôi đã thay đổi một biến 'int' thành' long' trong nguồn SharpZip để tránh tràn. * Tôi sẽ phải thử tìm mã SharpZip cố định cũ của mình và kiểm tra xem nó có khớp với * mới nhất không. –