Tạo tập tin Zip với .NET 5

Tập tin Zip là định dạng nén phổ biến nhất trong lịch sử máy tính, nó được phát minh lần đầu tiên vào năm 1986 bởi Phillip Katz. Kể từ đó, tập tin Zip đã được đưa vào mọi hệ điều hành như một phương pháp nén phổ biến.

Trong bài viết này, chúng ta sẽ tìm hiểu lớp tiện ích ZipFile trong namespace System.IO.Compression, cách nén tập tin và thư mục, cùng với giải nén tập tin zip.

Sử dụng lớp ZipFile trong namespace System.IO.Compression

Microsoft đã giới thiệu lớp tiện ích ZipFile trong .NET Framework 4.5 và các nhà phát triển có thể sử dụng lớp tiện ích này trên .NET 5, .NET Core 1.0+, UWP và Xamarin.Forms.

Lớp ZipFile phụ thuộc vào quyền truy cập vào hệ thống tập tin; như vậy, bất kỳ ứng dụng nào muốn sử dụng lớp này cũng cần tham chiếu đến assembly System.IO.Compression.FileSystem.

Ví dụ tạo một tập tin Zip

Lớp ZipFile có một phương thức CreateFromDirectory nhận các tham số đầu vào là một thư mục đích và một đường dẫn cho tập tin zip kết quả.

using System;
using System.IO;
using System.IO.Compression;

// using a target directory
// ZipFile will create
// the zip file on disk
ZipFile.CreateFromDirectory(
    @"./",
    @"./archive.zip"
);

Sử dụng phương thức CreateFromDirectory, chúng ta có thể thiết lập một số biến, bao gồm cả mức độ nén là Fastest, Optimal NoCompression. Mức độ nén mặc định được thiết lập là Optimal và được thiết lập nội bộ trong lớp ZipEntry khi chúng ta không cung cấp giá trị.

using System;
using System.IO;
using System.IO.Compression;

ZipFile.CreateFromDirectory(
    @"./", 
     "archive.zip", 
    compressionLevel: CompressionLevel.Fastest, 
    includeBaseDirectory: false, 
    entryNameEncoding: Encoding.UTF8);

Đối với các nhà phát triển muốn kiểm soát nhiều hơn việc nén một thư mục, họ có thể duyệt qua nội dung của thư mục và thêm các tập tin riêng lẻ.

Kỹ thuật sau đây rất hữu ích khi chúng ta chỉ muốn thêm các tập tin cụ thể, tức là các tập tin hình ảnh hoặc video.

Điều quan trọng là phải gọi phương thức Dispose để đảm bảo việc tạo ra một tập tin zip hợp lệ bằng cách sử dụng từ khóa using.

Trong ví dụ dưới đây, chúng ta đang khai báo một biến phạm vi với từ khóa using.

using System;
using System.IO;
using System.IO.Compression;

var images = Directory.GetFiles(@"./", "*.png");

if (File.Exists("archive.zip"))
    File.Delete("archive.zip");

using var archive = 
    ZipFile
    .Open(@"archive.zip", ZipArchiveMode.Create);

foreach (var image in images)
{
    var entry =
        archive.CreateEntryFromFile(
            image,
            Path.GetFileName(image),
            CompressionLevel.Optimal
        );
    
    Console.WriteLine($"{entry.FullName} was compressed.");
}

Nếu chúng ta cần lưu trữ một thực thể chỉ tồn tại trong bộ nhớ, chúng ta có thể sử dụng các đối tượng Stream. Chúng ta có thể sử dụng phương thức CopyToAsync được tìm thấy trên hầu hết các đối tượng Stream để sao chép trực tiếp vào thể hiện của ZipEntry của chúng ta.

using System;
using System.IO;
using System.IO.Compression;

var images = Directory.GetFiles(@"./", "*.png");
if (File.Exists("archive.zip"))
    File.Delete("archive.zip");
using var archive =
    ZipFile
        .Open(@"archive.zip", ZipArchiveMode.Create);

// we're getting a file stream
// here but it could be any stream
var file = File.OpenRead(images[0]);
var entry =
    archive.CreateEntry(
        "test.png",
        CompressionLevel.Optimal
    );
await file.CopyToAsync(entry.Open());
Console.WriteLine($"{entry.FullName} was compressed.");

Đây là một số cách để tạo tập tin zip trong ứng dụng C#, nhưng còn việc truy xuất các phần tử từ tập tin zip thì sao?

Ví dụ giải nén tập tin Zip

Cách tiếp cận đơn giản nhất là sử dụng phương thức ExtractToDirectory được tìm thấy trên lớp ZipFile. Phương thức này sẽ ghi các phần thử trong tập tin zip vào một thư mục trên đĩa, sau đó chúng ta có thể truy cập bằng hệ thống tập tin của mình.

using System;
using System.IO;
using System.IO.Compression;

ZipFile.ExtractToDirectory(
    @"./archive.zip",
    @"./destination_directory",
    overwriteFiles: true
);

Nếu chúng ta cần thực hiện xử lý hậu kỳ cho các phần tử của tập tin zip, chúng ta có thể sử dụng phương thức OpenFile của lớp ZipFile để tạo một thể hiện của ZipArchive.

using System;
using System.IO;
using System.IO.Compression;

var archive = ZipFile.OpenRead(@"./archive.zip");

foreach (var entry in archive.Entries)
{
    Console.WriteLine(entry.Name);
    var stream = entry.Open();
    
    // read stream
    // push to the cloud?
    // do whatever you like!
}

Như chúng ta có thể thấy, quá trình làm việc với tập tin zip và nội dung của nó rất đơn giản và khả năng làm việc với các đối tượng Stream cho phép chúng ta chuyển tài nguyên từ tập tin zip sang bất kỳ cơ chế lưu trữ nào khác.

Phần kết luận

Tập tin zip là định dạng tập tin cần thiết để nhà phát triển có thể dùng để nén và lưu trữ dữ liệu. Mặc dù không phải là định dạng nén hiệu quả nhất, nhưng nó lại phổ biến và được hiểu bởi tất cả các công nghệ.

Nó cho phép chúng ta chuyển các tập tin được nhóm hợp lý trong một luồng dữ liệu duy nhất, có thể hữu ích trong nhiều trường hợp người dùng. May mắn cho các nhà phát triển .NET, lớp tiện ích ZipFile cung cấp quá đủ chức năng để làm việc với phương pháp nén này, cùng với vô số cách chúng ta có thể làm việc với định dạng tập tin này.

Nếu bạn thấy bài viết này hữu ích, hãy chia sẻ nó với bạn bè và đồng nghiệp của bạn. Như mọi khi, cảm ơn vì đã đọc.

Nếu Comdy hữu ích và giúp bạn tiết kiệm thời gian làm việc

Bạn có thể vui lòng đưa Comdy vào whitelist của trình chặn quảng cáo ❤️ để hỗ trợ chúng tôi trong việc trả tiền cho dịch vụ lưu trữ web để duy trì hoạt động của trang web.

Lập Trình C#
Bài Viết Liên Quan:
Đọc và ghi file Excel trong C#
Trung Nguyen 29/10/2021
Đọc và ghi file Excel trong C#

Bài viết này sẽ giới thiệu cách đơn giản nhất mà tôi đã tìm thấy để đọc và ghi file Excel bằng C# sử dụng ExcelMapper.

Làm việc với PriorityQueue của .NET 6
Trung Nguyen 25/10/2021
Làm việc với PriorityQueue của .NET 6

Bài viết này sẽ giúp bạn tìm hiểu PriorityQueue của .NET 6 là gì, cách chúng ta thêm các phần tử và cách chúng ta có thể xếp hàng lại cho các phần tử.

Hướng dẫn nhanh và ví dụ về pattern matching trong C#
Trung Nguyen 23/10/2021
Hướng dẫn nhanh và ví dụ về pattern matching trong C#

Bài viết này sẽ trình bày một số ví dụ về pattern matching hữu ích và bạn có thể xem xét sử dụng trong các dự án hiện tại hoặc tương lai của bạn.

Sử dụng chuỗi kết nối Redis-CLI trong StackExchange.Redis
Trung Nguyen 18/10/2021
Sử dụng chuỗi kết nối Redis-CLI trong StackExchange.Redis

Bài viết này sẽ hướng dẫn chúng ta cách viết một phương thức mở rộng để phân tích chuỗi kết nối redis-cli có thể sử dụng với thư viện StackExchange.Redis.