Cơ sở kiến thức

Nén hoặc giải nén tệp bằng C# - Nén và giải nén tệp

ZIP là gì (định dạng tệp)

ZIP là một định dạng tệp lưu trữ hỗ trợ nén dữ liệu không mất mát. Một tệp ZIP có thể chứa một hoặc nhiều tệp hoặc thư mục đã được nén. Các tệp ZIP thường sử dụng phần mở rộng .zip hoặc .ZIP và loại MIME application/zip. ZIP được nhiều chương trình sử dụng làm định dạng tệp cơ bản, thường dưới một tên khác. Khi duyệt hệ thống tệp qua giao diện người dùng, các biểu tượng đồ họa đại diện cho tệp ZIP thường xuất hiện dưới dạng tài liệu hoặc đối tượng khác nổi bật với hình ảnh kéo khóa.

nhiều cách để nén (compress) tệp , tùy thuộc vào hệ điều hành bạn đang dùng. Hàng ngày, chúng ta thường phải nén hoặc giải nén một số tệp và chuyển chúng tới máy chủ lưu trữ hoặc nền tảng chia sẻ tệp. May mắn là chúng ta có thể tự động hoá quy trình này bằng cách sử dụng Aspose.ZIP API . Nó cho phép bạn nén và giải nén tệp mà không lo lắng về cấu trúc tệp nền. Bài viết này trình bày cách làm việc với nén tệp đơn và nén nhiều tệp.

Aspose.ZIP package có thể được thêm vào dự án .NET của bạn bằng lệnh NuGet sau:

PM> Install-Package Aspose.Zip

Cách nén một tệp đơn bằng C#

  1. Đầu tiên chúng ta cần tạo một đối tượng của lớp FileStream class cho kho lưu trữ ZIP đầu ra
  2. Tải một tệp duy nhất vào đối tượng FileStream
  3. Tạo một đối tượng của Archive class
  4. Thêm tệp vào archive bằng phương thức Archive.CreateEntry (“FileName”, FileStream)
  5. Tạo archive ZIP bằng phương thức Archive.Save (FileStream)
        using (FileStream zipFile = File.Open(dataDir + "CompressSingleFile_out.zip", FileMode.Create))
        {
            //File to be added to archive
            using (FileStream source1 = File.Open(dataDir + "alice29.txt", FileMode.Open, FileAccess.Read))
            {
                    using (var archive = new Archive(new ArchiveEntrySettings()))
                {
                    archive.CreateEntry("alice29.txt", source1);
                    archive.Save(zipFile);
                }
            }
        }

Nén nhiều tệp bằng C#

Sự khác biệt giữa nén một tệp và nén nhiều tệp là chúng ta phải tải nhiều tệp hơn vào FileStream và thêm chúng vào archive ZIP bằng phương thức Archive.CreateEntry("FileName", FileStream). Đoạn mã dưới đây minh họa cách thêm nhiều tệp vào ZIP bằng FileStream.

        // Create FileStream for output ZIP archive
        using (FileStream zipFile = File.Open("compressed_files.zip", FileMode.Create))
        {
	        // File to be added to archive
	        using (FileStream source1 = File.Open("alice29.txt", FileMode.Open, FileAccess.Read))
	            {
		            // File to be added to archive
		            using (FileStream source2 = File.Open("asyoulike.txt", FileMode.Open, FileAccess.Read))
		        {
			        using (var archive = new Archive())
			            {
				            // Add files to the archive
				            archive.CreateEntry("alice29.txt", source1);
				            archive.CreateEntry("asyoulik3.txt", source2);
				            // ZIP the files
				            archive.Save(zipFile, new ArchiveSaveOptions() { Encoding = Encoding.ASCII, ArchiveComment = "two files are compressed in this archive" });
		            	}
		        }
	        }
        }

Nén tệp bằng lớp FileInfo

Các tệp cũng có thể được tải bằng lớp FileInfo và sau đó thêm vào archive ZIP theo cách tương tự như trên.
Lớp FileInfo cung cấp các thuộc tính và phương thức để tạo, sao chép, xóa, di chuyển và mở tệp, đồng thời hỗ trợ tạo các đối tượng FileStream.

    using (FileStream zipFile = File.Open("compressed_files.zip", FileMode.Create))
    {
	    // Files to be added to archive
	    FileInfo fi1 = new FileInfo("alice29.txt");
	    FileInfo fi2 = new FileInfo("fields.c");
	    using (var archive = new Archive())
	        {
		        // Add files to the archive
		        archive.CreateEntry("alice29.txt", fi1);
		        archive.CreateEntry("fields.c", fi2);
		        // Create ZIP archive
		        archive.Save(zipFile, new ArchiveSaveOptions() { Encoding = Encoding.ASCII });
	        }
    }

Lưu tệp vào archive mà không nén

    //Creates zip archive without compressing files
    using (FileStream zipFile = File.Open(dataDir + "StoreMultipleFilesWithoutCompression_out.zip", FileMode.Create))
    {
    FileInfo fi1 = new FileInfo(dataDir + "alice29.txt");
    FileInfo fi2 = new FileInfo(dataDir + "lcet10.txt");

    using (Archive archive = new Archive(new ArchiveEntrySettings(new StoreCompressionSettings())))
    {
        archive.CreateEntry("alice29.txt", fi1);
        archive.CreateEntry("lcet10.txt", fi2);
        archive.Save(zipFile, new ArchiveSaveOptions() { Encoding = Encoding.ASCII });
    }
    }  

Cách ZIP tệp có mật khẩu trong C#

    using (var archive = new Archive(new ArchiveEntrySettings(encryptionSettings: new TraditionalEncryptionSettings("pass"))))
    {
    archive.CreateEntry("entry_name1.dat", "input_file1.dat");
    archive.CreateEntry("entry_name2.dat", "input_file2.dat");
    archive.Save("result_archive.zip");
    }

Tham số encryptionSettings được dùng để tạo một archive ZIP có bảo vệ bằng mật khẩu.

Cách UNZIP tệp có mật khẩu trong C#

    using (var archive = new Archive("input_archive.zip", new ArchiveLoadOptions{DecryptionPassword = "pass"}))
    {
    archive.ExtractToDirectory("\\outputDirectory");
    }

ArchiveLoadOptions với thuộc tính DecryptionPassword được dùng để mở một archive ZIP có bảo vệ bằng mật khẩu.
Để xem các ví dụ đầy đủ và tệp dữ liệu, vui lòng truy cập https://github.com/aspose-zip/Aspose.ZIP-for-.NET .

Sử dụng nén LZMA trong archive ZIP

Thuật toán Lempel–Ziv–Markov chain (LZMA) là một thuật toán thực hiện nén dữ liệu không mất mát. LZMA sử dụng thuật toán nén từ điển, luồng dữ liệu nén là một chuỗi các bit. Nén LZMA trong archive ZIP cho phép các container ZIP chứa các mục đã được nén bằng LZMA. Đoạn mã dưới đây minh họa việc triển khai nén LZMA bằng Aspose.ZIP API .

using (FileStream zipFile = File.Open(dataDir + "LZMACompression_out.zip", FileMode.Create))
{
    using (Archive archive = new Archive(new ArchiveEntrySettings(new LzmaCompressionSettings())))
    {
        archive.CreateEntry("sample.txt", dataDir + "sample.txt");
        archive.Save(zipFile);
    }
}

Sử dụng nén BZip2 trong archive ZIP

bzip2 là một chương trình nén tệp miễn phí và mã nguồn mở sử dụng thuật toán Burrows–Wheeler. Nó chỉ nén các tệp đơn và không phải là một trình lưu trữ tệp. Được phát triển bởi Julian Seward và được duy trì bởi Mark Wielaard và Micah Snyder. Đoạn mã dưới đây minh họa việc triển khai nén BZip2 bằng Aspose.ZIP API .

using (FileStream zipFile = File.Open(dataDir + "Bzip2Compression_out.zip", FileMode.Create))
{
    using (Archive archive = new Archive(new ArchiveEntrySettings(new Bzip2CompressionSettings())))
    {
        archive.CreateEntry("sample.txt", dataDir + "sample.txt");
        archive.Save(zipFile);
    }
}

Sử dụng nén PPMd trong archive ZIP

Prediction by partial matching (PPM) là một kỹ thuật nén dữ liệu thống kê thích ứng dựa trên mô hình ngữ cảnh và dự đoán. Các mô hình PPM sử dụng một tập hợp các ký tự trước đó trong luồng ký tự chưa nén để dự đoán ký tự tiếp theo. Thuật toán PPM cũng có thể được dùng để nhóm dữ liệu thành các nhóm dự đoán trong phân tích cụm. Đoạn mã dưới đây minh họa việc triển khai nén PPMd bằng Aspose.ZIP API .

using (FileStream zipFile = File.Open(dataDir + "PPMdCompression_out.zip", FileMode.Create))
{
    using (Archive archive = new Archive(new ArchiveEntrySettings(new PPMdCompressionSettings())))
    {
        archive.CreateEntry("sample.txt", dataDir + "sample.txt");
        archive.Save(zipFile);
    }
}

Giải nén archive với một tệp duy nhất

using (FileStream fs = File.OpenRead(dataDir + "CompressSingleFile_out.zip"))
{
    using (Archive archive = new Archive(fs))
    {
        int percentReady = 0;
        archive.Entries[0].ExtractionProgressed += (s, e) =>
        {
            int percent = (int)((100 * e.ProceededBytes) / ((ArchiveEntry)s).UncompressedSize);
            if (percent > percentReady)
            {
                Console.WriteLine(string.Format("{0}% decompressed", percent));
                percentReady = percent;
            }
        };
        archive.Entries[0].Extract(dataDir + "alice_extracted_out.txt");
    }
}

Giải nén archive với nhiều tệp

using (FileStream zipFile = File.Open(dataDir + "CompressMultipleFiles_out.zip", FileMode.Open))
{
    StringBuilder sb = new StringBuilder("Entries are: ");
    int percentReady = 0;
    using (Archive archive = new Archive(zipFile,
        new ArchiveLoadOptions()
        {
            EntryListed = (s, e) => { sb.AppendFormat("{0}, ", e.Entry.Name); },
            EntryExtractionProgressed = (s, e) =>
            {
                int percent = (int)((100 * e.ProceededBytes) / ((ArchiveEntry)s).UncompressedSize);
                if (percent > percentReady)
                {
                    Console.WriteLine(string.Format("{0}% compressed", percent)); percentReady = percent;
                }
            }
        }))
    {
        Console.WriteLine(sb.ToString(0, sb.Length - 2));
        using (var extracted = File.Create(dataDir + "alice_extracted_out.txt"))
        {
            using (var decompressed = archive.Entries[0].Open())
            {
                byte[] buffer = new byte[8192];
                int bytesRead;
                while (0 < (bytesRead = decompressed.Read(buffer, 0, buffer.Length)))
                {
                    extracted.Write(buffer, 0, bytesRead);
                }
                // Read from decompressed stream to extracting file.
            }
        }
        percentReady = 0;
        archive.Entries[1].Extract(dataDir + "asyoulik_extracted_out.txt");
    }
}

Trích xuất archive đã lưu mà không nén

using (FileStream zipFile = File.Open(dataDir + "StoreMultipleFilesWithoutCompression_out.zip", FileMode.Open))
{
    using (Archive archive = new Archive(zipFile))
    {
        using (var extracted = File.Create(dataDir + "alice_extracted_store_out.txt"))
        {
            using (var decompressed = archive.Entries[0].Open())
            {
                byte[] buffer = new byte[8192];
                int bytesRead;
                while (0 < (bytesRead = decompressed.Read(buffer, 0, buffer.Length)))
                {
                    extracted.Write(buffer, 0, bytesRead);
                }
                // Read from decompressed stream to extracting file.
            }
        }

        using (var extracted = File.Create(dataDir + "asyoulik_extracted_store_out.txt"))
        {
            using (var decompressed = archive.Entries[1].Open())
            {
                byte[] buffer = new byte[8192];
                int bytesRead;
                while (0 < (bytesRead = decompressed.Read(buffer, 0, buffer.Length)))
                {
                    extracted.Write(buffer, 0, bytesRead);
                }
                // Read from decompressed stream to extracting file.
            }
        }
    }
}

Để xem các ví dụ đầy đủ và tệp dữ liệu, vui lòng truy cập https://github.com/aspose-zip/Aspose.ZIP-for-.NET .