15 thg 10, 2010

Nén hoặc giải nén một file hay một thư mục

Khi lập trình có khi bạn gặp phải vấn đề là nén hoặc giải nén một file, một thư mục hoặc copy file hoặc thư mục. Trong bài viết này mình sẽ hướng dẫn các bạn sử dụng thư viện ICSharpCode.SharpZipLib để thực hiện điều đó
Lấy ví dụ một ứng dụng để bạn cần nén và copy file đã nén  là dữ liệu quan trọng của bạn chẳng hạn. Bạn có 1 Database có dữ liệu quan trọng cần backup hàng ngày và bạn đã đặt lịch backup định kỳ cho nó trong SQL, sau khi backup song  bạn cho thực hiện việc nén và copy file nén này sang một thuc mục khác hoặc sang một máy khác (cùng mạng Lan) đảm bảo an toàn dữ liệu hơn.
Trước tiên bạn cần download thư viện ICSharpCode.SharpZipLib tại đây.
Trong thư viện viện này cho phép bạn chọn các định dạng file nén, *.zip, *.rar, ... Trong bài này mình chỉ giới thiệu các bạn cách nén với định dang *.zip. Sau khi download về giải nén rồi bạn copy thư viện đó vào thư mục Bin của ứng dụng. Sau đây là các hàm thực hiện nén và giải nén.
1. Hàm nén các file trong một thư mục.
Để nén các gile trong thư mục bạn dùng hàm sau:
01/// <summary>
02/// Create by: hungbv@hmweb.com.vn
03/// Nén tất các các files trong sPath vào fileZip
04/// </summary>
05/// <param name="sPath"></param>
06/// <param name="fileZip"></param>
07private static void NenMotThuMuc(string sPath, string fileZip)
08{
09    ZipOutputStream zipOut = new ZipOutputStream(File.Create(fileZip));
10    foreach (string fName in Directory.GetFiles(sPath))
11    {
12        FileInfo fi = new FileInfo(fName);
13        ZipEntry entry = new ZipEntry(fi.Name);
14        FileStream sReader = File.OpenRead(fName);
15        byte[] buff = new byte[Convert.ToInt32(sReader.Length)];
16        sReader.Read(buff, 0, (int)sReader.Length);
17        entry.DateTime = fi.LastWriteTime;
18        entry.Size = sReader.Length;
19        sReader.Close();
20        zipOut.PutNextEntry(entry);
21        zipOut.Write(buff, 0, buff.Length);
22    }
23    zipOut.Finish();
24    zipOut.Close();
25}
 2. Hàm giải nén một file *.zip
Để giải nén một file.zip bạn thực hiện với hàm sau sẽ giải nén và đưa tất cả các gile trong file nén vào thư mục newFolder
01/// <summary>
02/// Create by: hungbv@hmweb.com.vn
03/// Giải nén một file.zip sFile vào thư mục newFolder
04/// </summary>
05/// <param name="sFile"></param>
06/// <param name="newFolder"></param>
07private static void GiaiNenMotFile(string sFile, string newFolder)
08{
09    ZipInputStream zipIn = new ZipInputStream(File.OpenRead(sFile));
10    ZipEntry entry;
11    while ((entry = zipIn.GetNextEntry()) != null)
12    {
13        FileStream streamWriter = File.Create(newFolder + entry.Name);
14        long size = entry.Size;
15        byte[] data = new byte[size];
16        while (true)
17        {
18            size = zipIn.Read(data, 0, data.Length);
19            if (size > 0) streamWriter.Write(data, 0, (int)size);
20            else break;
21        }
22        streamWriter.Close();
23    }
24}
Tiếp theo mình sẽ giới thiệu là hàm liệt kê tất cả các file có trong một file nén
3. Hàm trả về danh sách các file trong một file nén
 Để xem trong một file nén có những file nào bạn sử dụng hàm sau:
01/// <summary>
02/// Trả về danh sách các file trong 1 file nén/// </summary>
03/// <param name="sFile"></param>
04/// <returns></returns>
05private static string ListZipContent(string sFile)
06{
07    string listfilename = "";
08    ZipFile zip = new ZipFile(File.OpenRead(sFile));
09    foreach (ZipEntry entry in zip)
10    {
11        listfilename += entry.Name + "<br>";
12    }
13    return listfilename;
14}
4. Hàm copy từ thư mục này đến thư mục khác
Để copy một thư mục, một file từ thư mục này đến thư mục khác bạn dụng hàm sau
01/// <summary>
02/// Copy thư mục hoặc file từ thư mục này đến thư mục khác
03/// </summary>
04/// <param name="ThuMucNguon"></param>
05/// <param name="ThucMucDich"></param>
06public static void CopyDirectory(DirectoryInfo ThuMucNguon, DirectoryInfo ThucMucDich)
07{
08    try
09    {
10        if (!ThucMucDich.Exists)
11        {
12            ThucMucDich.Create();
13        }
14        FileInfo[] files = ThuMucNguon.GetFiles();
15        foreach (FileInfo file in files)
16        {
17            if ((System.IO.File.Exists(System.IO.Path.Combine(ThucMucDich.FullName, file.Name))) == false)
18            {
19                file.CopyTo(Path.Combine(ThucMucDich.FullName, file.Name));
20            }
21        }
22        //Xử lý thư mục con
23        DirectoryInfo[] dirs = ThuMucNguon.GetDirectories();
24        foreach (DirectoryInfo dir in dirs)
25        {
26            string ThucMucDichDir = Path.Combine(ThucMucDich.FullName, dir.Name);
27            CopyDirectory(dir, new DirectoryInfo(ThucMucDichDir));
28        }
29 
30    }
31    catch { }
32}
Hàm trên chỉ copy thư mục hoặc file chưa có trong thư mục đích. Vậy muốn copy một file đã có triong thư mục địch bạn cần viết hàm khác. Hàm đó mình viết như sau:
5. Hàm copy từ thư mục này đến thư mục khác - Overwrite
01private void CopyDirectory_Overwrite(string ThuMucNguonPath, string destPath, bool overwrite)
02{
03    System.IO.DirectoryInfo ThuMucNguonDir = new System.IO.DirectoryInfo(ThuMucNguonPath);
04    System.IO.DirectoryInfo destDir = new System.IO.DirectoryInfo(destPath);
05    if (ThuMucNguonDir.Exists)
06    {
07        if (!destDir.Exists)
08            destDir.Create();
09        foreach (System.IO.FileInfo file in ThuMucNguonDir.GetFiles())
10        {
11            if (overwrite)
12                file.CopyTo(System.IO.Path.Combine(destDir.FullName, file.Name));
13            else if ((System.IO.File.Exists(System.IO.Path.Combine(destDir.FullName, file.Name))) == false)
14                file.CopyTo(System.IO.Path.Combine(destDir.FullName, file.Name), false);
15        }
16        foreach (System.IO.DirectoryInfo dir in ThuMucNguonDir.GetDirectories())
17        {
18            CopyDirectory_Overwrite(dir.FullName, System.IO.Path.Combine(destDir.FullName, dir.Name), overwrite);
19        }
20    }
21}
Vì dụ nhé trong ổ D của mình có một thư mục là flyout Giờ mình muốn nén thư mục này theo thành flyout+ddMMyyy.zip thì trong Page_Load (Hoặc trong sự kiện Onclick của bạn) mình chỉ cần gọi hàm như sau:
NenMotThuMuc(@"D:\flyout", @"D:\flyout" + DateTime.Now.ToString("ddMMyyyy") + ".zip");
Khi đó mình sẽ được file flyout05062010.zip. Tiếp theo mình sử dụng hàm ListZipContent để kiểm tra như sau:
Label1.Text = ListZipContent(@"D:\flyout05062010.zip"); Sẽ cho kết quả là:
flyout.rar
index.html
style.css

Chúc bạn thành công

Không có nhận xét nào:

Đăng nhận xét