Nén và giải nén trong C#
1. Sơ đồ phân cấp các lớp
Dưới đây là danh mục các class sử dụng cho mục đích nén và giải nén file. Chúng nằm trong namespace System.IO.Compression.
Class | Mô tả |
ZipFile | Cung cấp các phương thức tĩnh cho việc tạo, trích dữ liệu và mở file dữ liệu zip. |
ZipArchive | Đại diện cho tập các file được nén trong một file có định dạng ZIP. |
ZipArchiveEntry | Đại diện cho một tập tin nằm trong file định dạng ZIP. |
DeflateStream | Cung cấp các phương thức và thuộc tính cho các luồng (stream) nén và giải nén bằng cách sử dụng thuật toán Deflate. |
GZipStream | Cung cấp các phương thức và thuộc tính được sử dụng để nén và giải nén các luồng (stream). |
Chú ý rằng các class này được đưa vào C# từ phiên bản 4.5, vì vậy project của bạn phải sử dụng .NET phiên bản 4.5 hoặc mới hơn.
2. ZipFile
Class ZipFile là một class tiện ích, nó có nhiều phương thức tĩnh giúp bạn mở file zip, trích lấy dữ liệu, hoặc các tình huống hay được sử dụng như nén một thư mục thành một file zip, giải nén file zip ra một thư mục, ..
Ví dụ đơn giản dưới đây sử dụng các phương thức tiện ích của class ZipFile nén một thư mục thành một file zip và sau đó giải nén file này sang một thư mục khác.
ZipDirectoryDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Compression;
namespace CompressionTutorial
{
class ZipDirectoryDemo
{
public static void Main(string[] args)
{
// Thư mục sẽ được nén.
string inputDir = "C:/test/inputdir";
// File đầu ra sau khi nén thư mục trên.
string zipPath = "C:/test/data.zip";
// Giải nén file zip ra một thư mục.
string extractPath = "C:/test/outputdir";
// Tạo ra file zip bằng cách nén một thư mục.
ZipFile.CreateFromDirectory(inputDir, zipPath);
// Giải nén file zip ra một thư mục.
ZipFile.ExtractToDirectory(zipPath, extractPath);
Console.WriteLine("Done!");
}
}
}
Nếu bạn nhận được một thông báo lỗi: "The name 'ZipFile' does not exist in the current context"(Mặc dù đã khai báo using System.IO.Compression) điều đó có nghĩa là project của bạn sử dụng .NET cũ hơn 4.5 hoặc chương trình không tìm thấy thư viện DLL. Bạn có thể xem cách fix lỗi này trong phụ lục ở cuối của tài liệu này.
Chạy ví dụ và nhận được kết quả:
- data.zip
3. ZipArchive
ZipArchive đại diện cho một bó các file đã nén trong một file định dạng ZIP. Bạn có thể tạo được đối tượng ZipArchive thông qua phương thức OpenRead của class ZipFile. Thông qua ZipArchive bạn có thể đọc các file con đã được nén trong file zip.
Ví dụ dưới đây liệt kê ra các ZipArchiveEntry có trong file zip.
ListArchiveEntryDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Compression;
using System.IO;
namespace CompressionTutorial
{
class ListArchiveEntryDemo
{
public static void Main(string[] args)
{
string zipPath = "c:/test/data.zip";
using (ZipArchive archive = ZipFile.OpenRead(zipPath))
{
// Duyệt danh sách các ZipArchiveEntry.
foreach (ZipArchiveEntry entry in archive.Entries)
{
Console.WriteLine("Entry:");
Console.WriteLine(" Name = " + entry.Name);
Console.WriteLine(" FullName = " + entry.FullName);
}
}
Console.Read();
}
}
}
Chạy ví dụ:
Entry:
Name = data.docx
FullName = data.docx
Entry:
Name = image.bmp
FullName = image.bmp
Entry:
Name = readme.txt
FullName = readme.txt
Entry:
Name = Dotnet.docx
FullName = documents\Dotnet.docx
Entry:
Name = java.docx
FullName = documents\java.docx
Trích các file dữ liệu trong file zip:
ExtractDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Compression;
using System.IO;
namespace CompressionTutorial
{
class ExtractDemo {
static void Main(string[] args)
{
string zipPath = "c:/test/data.zip";
// Thư mục đầu ra để giải nén ra.
string extractPath = "c:/test/extract";
// Nếu thư mục không tồn tại, tạo nó.
if (!Directory.Exists(extractPath))
{
System.IO.Directory.CreateDirectory(extractPath);
}
using (ZipArchive archive = ZipFile.OpenRead(zipPath))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
Console.WriteLine("Found: " + entry.FullName);
// Tìm kiếm các Entry có đuôi .docx
if (entry.FullName.EndsWith(".docx", StringComparison.OrdinalIgnoreCase))
{
// Ví dụ: documents/Dotnet.docx
Console.WriteLine(" - Extract entry: " + entry.FullName);
// C:/test/extract/documents/Dotnet.docx ...
string entryOuputPath = Path.Combine(extractPath, entry.FullName);
Console.WriteLine(" - Entry Ouput Path: " + entryOuputPath);
FileInfo fileInfo = new FileInfo(entryOuputPath);
// Đảm bảo rằng thưc mục chứa file này tồn tại.
// Ví dụ: C:/test/extract/documents
fileInfo.Directory.Create();
// Ghi đè (overwrite) file cũ nếu nó đã tồn tại.
entry.ExtractToFile(entryOuputPath,true);
}
}
}
Console.ReadLine();
}
}
}
Chạy ví dụ:
Found: data.docx
- Extract entry: data.docx
- Entry Output Path: c:/test/extract\data.docx
Found: image.bmp
Found: readme.txt
Found: documents\Dotnet.docx
- Extract entry: documents\Dotnet.docx
- Entry Output Path: c:/test/extract\documents\Dotnet.docx
Found: documents\java.docx
- Extract entry: documents\java.docx
- Entry Output Path: c:/test/extract\documents\java.docx
Bạn cũng có thể trèn thêm các file vào trong một file zip có sẵn.
AddEntryDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Compression;
using System.IO;
namespace CompressionTutorial
{
class AddEntryDemo
{
static void Main(string[] args)
{
string zipPath = "C:/test/data.zip";
// Mở một Stream để đọc file zip.
using (FileStream zipStream = new FileStream(zipPath, FileMode.Open))
{
// Tạo đối tượng ZipArchive.
using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Update))
{
// Thêm một entry vào ZipArchive.
ZipArchiveEntry readmeEntry = archive.CreateEntry("note/Note.txt");
// Tạo một Stream để ghi nội dung vào entry.
using (StreamWriter writer = new StreamWriter(readmeEntry.Open()))
{
writer.WriteLine("## Note.txt");
writer.WriteLine("========================");
}
}
}
}
}
}
Chạy ví dụ và nhận được kết quả.
4. Phụ lục: Khắc phục lỗi
Khi bạn nhận được lỗi: "The name 'ZipFile' does not exist in the current context"(Mặc dù đã khai báo using System.IO.Compression) điều đó có nghĩa là bạn đã sử dụng .NET cũ hơn phiên bản 4.5 hoặc chương trình không tìm được thư viện DLL cần thiết.
Nhấn phải chuột vào Project chọn Properties, đảm bảo rằng project của bạn đã sử dụng .NET Framework 4.5 trở lên.
Chạy lại class của bạn xem trình biên dịch còn thông báo lỗi đó nữa hay không. Trong trường hợp vẫn thông báo lỗi bạn cần chỉ định rõ vị trí thư viện DLL.
- C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.IO.Compression.FileSystem.dll
- C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.IO.Compression.FileSystem.dll
Nhấn phải chuột vào Project chọn:
- Add/Reference..
Chọn file:
- System.IO.Compression.FileSystem.dll
Tương tự nếu bạn nhận được thông báo "The name 'ZipArchive' does not exist in the current context" (Mặc dù đã khai báo using System.IO.Compression) bạn cần khai báo sử dụng thư viện System.IO.Compression.dll:
Tương tự nếu bạn nhận được thông báo "The name 'Path' does not exist in the current context" (Mặc dù đã khai báo using System.IO) bạn cần khai báo sử dụng thư viện mscorlib.dll:
Các hướng dẫn lập trình C#
- Thừa kế và đa hình trong C#
- Bắt đầu với C# cần những gì?
- Học nhanh C# cho người mới bắt đầu
- Cài đặt Visual Studio 2013 trên Windows
- Abstract class và Interface trong C#
- Cài đặt Visual Studio 2015 trên Windows
- Nén và giải nén trong C#
- Hướng dẫn lập trình đa luồng trong C#
- Hướng dẫn và ví dụ C# Delegate và Event
- Cài đặt AnkhSVN trên Windows
- Lập trình C# theo nhóm sử dụng Visual Studio và SVN
- Cài đặt .Net Framework
- Access Modifier trong C#
- Hướng dẫn và ví dụ C# String và StringBuilder
- Hướng dẫn và ví dụ C# Property
- Hướng dẫn và ví dụ C# Enum
- Hướng dẫn và ví dụ C# Structure
- Hướng dẫn và ví dụ C# Generics
- Hướng dẫn xử lý ngoại lệ trong C#
- Hướng dẫn và ví dụ Date Time trong C#
- Thao tác với tập tin và thư mục trong C#
- Hướng dẫn sử dụng Stream - luồng vào ra nhị phân trong C#
- Hướng dẫn sử dụng biểu thức chính quy trong C#
- Kết nối cơ sở dữ liệu SQL Server trong C#
- Làm việc với cơ sở dữ liệu SQL Server trong C#
- Kết nối cơ sở dữ liệu MySQL trong C#
- Làm việc với cơ sở dữ liệu MySQL trong C#
- Kết nối cơ sở dữ liệu Oracle trong C# không cần Oracle Client
- Làm việc với cơ sở dữ liệu Oracle trong C#
Show More