Thành viên
 
 
 
Zip thư mục để download và giải nén file Zip khi upload
  Trung bình: 3.1 (Đã có 8 lượt đánh giá)
   14/08/2012 10:07 AM

Thao tác download cả một thư mục thay vì phải download lần lượt các file sẽ tạo sự thuận tiện cho người dùng rất nhiều. Tương tự như vậy thay vì việc phải upload nhiều file đơn lẻ, người dùng có thể upload chỉ một file zip và sau đó website sẽ tự động giải nén đảm bảo đúng cấu trúc thư mục. Trong bài viết này, tôi sẽ trình bày cách đơn giản thực hiện các thao tác trên với thư viện ICSharpCode.SharpZipLib.dll 

Chuẩn bị

Vào http://www.icsharpcode.net/opensource/sharpziplib/Download.aspx download thư viện SharpZipLib.
Tạo mới Web Project.
Tạo mới file Default.aspx

Thực hiện

Trang Default thực hiện 2 tính năng demo:
- Download file zip với các file nằm trong thư mục data (chuẩn bị vài file và thư mục trong đó)
- Upload file zip và giải nén vào trong thư mục upload

Tôi sử dụng các lớp trong thư viện SharpZipLib để viết thành 2 hàm:
void CompressFolder(DirectoryInfo directory, ZipOutputStream zipStream, int folderOffset): nén các file trong thư mục directory vào trong luồng zipStream.
void UnpackZipFile(Stream zipStream, string outFolder): giải nén file zip ra thư mục outFolder

Tôi cài đặt hai hàm đó như sau:

private readonly byte[] _buffer = new byte[4096];
private void CompressFolder(DirectoryInfo directory, ZipOutputStream zipStream, int folderOffset)
{
	var files = directory.GetFiles();
	foreach (var fi in files)
	{
		// Lấy tên file trong file nén dựa trên tên file
		string entryName = fi.FullName.Substring(folderOffset);
		// Xóa bỏ tên ổ hoặc các dấu \
		entryName = ZipEntry.CleanName(entryName);
		var newEntry = new ZipEntry(entryName) { DateTime = fi.LastWriteTime, IsUnicodeText = true };
		// Nếu muốn mã hóa thì gán newEntry.AESKeySize bằng 128 hoặc 256, khi đó phải gán Password cho zipStream

		// thêm entry
		zipStream.PutNextEntry(newEntry);

		// lưu entry
		using (FileStream fs = fi.OpenRead())
		{
			int count = fs.Read(_buffer, 0, _buffer.Length);
			while (count > 0)
			{
				zipStream.Write(_buffer, 0, count);
				count = fs.Read(_buffer, 0, _buffer.Length);
				if (!Response.IsClientConnected)
				{
					break;
				}
				Response.Flush();
			}
		}
		zipStream.CloseEntry();
	}

	// lấy danh sách các folder con và thêm vào file nén
	var folders = directory.GetDirectories();
	foreach (var folder in folders)
	{
		CompressFolder(folder, zipStream, folderOffset);
	}
}

public void UnpackZipFile(Stream zipStream, string outFolder)
{
	var zipInputStream = new ZipInputStream(zipStream);
	ZipEntry zipEntry = zipInputStream.GetNextEntry();
	while (zipEntry != null)
	{
		string entryFileName = zipEntry.Name;

		string fullZipToPath = Path.Combine(outFolder, entryFileName);
		string directoryName = Path.GetDirectoryName(fullZipToPath);
		if (!string.IsNullOrEmpty(directoryName))
			Directory.CreateDirectory(directoryName);

		using (FileStream streamWriter = File.Create(fullZipToPath))
		{
			StreamUtils.Copy(zipInputStream, streamWriter, _buffer);
		}
		zipEntry = zipInputStream.GetNextEntry();
	}
}

Để xử lý khi click vào nút Download, tôi cài đặt hàm xử lý:

protected void btnDownload_Click(object sender, EventArgs e)
{
// Đặt tên file cho người dùng tải xuống là Data.zip
Response.AddHeader("Content-Disposition", "attachment;filename=\"Data.zip\"");
Response.ContentType = "application/zip";

var zos = new ZipOutputStream(Response.OutputStream);
// Gán zos.Password nếu muốn đặt mật khẩu

var path = Server.MapPath("~/data/");
var folderOffset = path.Length + (path.EndsWith("\\") ? 0 : 1);
CompressFolder(new DirectoryInfo(path), zos, folderOffset);

zos.IsStreamOwner = true;
zos.Close();
Response.End();
}

Và hàm xử lý cho nút Upload:

protected void btnUpload_Click(object sender, EventArgs e)
{
    if (fileUpload.HasFile && fileUpload.FileName.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase))
        UnpackZipFile(fileUpload.FileContent, Server.MapPath("~/upload/"));
}

Như vậy chỉ cần vài dòng code đơn giản bạn đã có thể tạo ra sự thuật tiện cho người dùng. Chúc các bạn thành công.
trích dẫn bài viết từ tek.eten.vn
 


Gửi bởi: linhlnp
Lượt xem: 2650

Quảng cáo Hải Phòng
Quảng cáo Hải Phòng
NHẬN XÉT CỦA BẠN
Trung bình: 3.1   
Kiểu gõ: Off Telex VNI VIQR Tổng hợp (Telex, Vni, Viqr)
Họ Tên:
Hòm thư:
Nội Dung:
Số ký tự còn lại: 3500