Bộ sưu tập

Nén và giải nén file với Java IO


https://codersontrang.com/2012/12/22/nen-va-giai-nen-file-voi-java-io/

Trong một số trường hợp có khi chúng ta sẽ cần phải nén các tập tin, ví dụ như khi chúng ta cần nén một loạt các file báo cáo, rồi attach vào email trước khi gửi cho người sử dụng. Và có thể có nhiều bạn nghĩ rằng việc nén và giải nén các file sẽ thật là cầu kì. Bài viết dưới đây xin trình bày cách để chúng ta nén và giải nén các tệp tin, với chỉ đơn giản bằng việc sử dụng các thư viện có sẵn của Java IO. Trong bài viết, chúng ta sẽ tạo một lớp tiện ích là ZipUtil.java. Lớp tiện ích này sẽ chứa các method để nén và giải nén các file.



ZipUtil.java


package com.wordpress.hautudu.ziptools;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

public class ZipUtil {
	private ZipUtil(){}
	public static boolean compress(List<File> sourceFiles, String zipFile, 
                                                         String zipDestination){
		boolean success = true;
		try{
			String zipFilePath = zipDestination.concat("/").concat(zipFile);
			FileOutputStream fos = new FileOutputStream(zipFilePath);
			ZipOutputStream zos = new ZipOutputStream(fos);
			
			byte [] buffer = new byte[1024];
			for(File f : sourceFiles){
				FileInputStream fis = new FileInputStream(f);
				zos.putNextEntry(new ZipEntry(f.getName()));
				int len;
				while((len = fis.read(buffer)) > 0){
					zos.write(buffer, 0, len);
				}
				zos.closeEntry();
				fis.close();
			}
			
			zos.close();
			fos.close();
		}catch(Exception e){
			success = false;
		}
		return success;
	}
	
	public static boolean extract(File zipFile, String extractDestination){
		boolean success = true;
		try{
			FileInputStream fis = new FileInputStream(zipFile);
			ZipInputStream zis = new ZipInputStream(fis);
			
			byte [] buffer = new byte[1024];
			ZipEntry entry;
			while((entry = zis.getNextEntry()) != null){
				FileOutputStream fos = new FileOutputStream(extractDestination
                                                                            .concat("/")
                                                                            .concat(entry.getName()));
				
				int len;
				while((len = zis.read(buffer)) > 0){
					fos.write(buffer, 0, len);
				}

				fos.close();
			}
			zis.close();
			fis.close();
		}catch(Exception e){
			success = false;
		}
		return success;
	}
}

Nhìn vào đoạn code trên, rõ ràng rằng việc nén và giải nén file cũng chỉ đơn giản giống như việc đọc và ghi file đơn thuần. Cách thức cũng tương tự như cách thức chúng ta copy một file từ nơi này đên nơi khác. Chỉ có điều ở đây, nội dung của các file ban đầu sẽ được tổ hợp lại trong một file mới có cấu trúc. Mỗi file ban đầu sẽ được biểu diễn tương ứng là một entry trong cấu trúc của file nén.

Bây giờ chúng ta sẽ tạo một lớp để kiểm tra hàm nén file ở trên. Ở ví dụ này chúng ta sẽ nén 3 file. Các file này là các file bất kì và không nhất thiết phải có cùng định dạng với nhau.

ZipUtil_1

Test nén file

TestCompression.java


package com.wordpress.hautudu.ziptools;

import java.io.File;
import java.util.List;
import java.util.ArrayList;

public class TestCompression {
	public static void main(String [] args){
		String zipDestination = "D:/ZipDemo";
		
		List<File> sourceFiles = new ArrayList<File>();
		String [] fileNames = {"My sheet.csv", 
                                       "Dreams_from_My_Father.pdf", 
                                       "Spring in Action.pdf"};
		
		for(String fileName : fileNames){
			File f = new File(zipDestination.concat("/").concat(fileName));
			sourceFiles.add(f);
		}
		
		String zipFile = "MyZip.zip";
		
		if(ZipUtil.compress(sourceFiles, zipFile, zipDestination)){
			System.out.println(fileNames.length+" file(s) compressed.");
		}else{
			System.out.println("Fail to compress files!");
		}
	}
}

Chạy chương trình thành công, một message sẽ xuất hiện ở console là “3 file(s) compressed.”. Chúng ta để ý thấy một file .zip sẽ xuất hiện trong thư mục. File này đương nhiên sẽ có dung lượng nhỏ hơn tổng kích thước của 3 file ban đầu. Để kiểm tra xem file nén này có “bình thường” hay không, chúng ta có thể dùng bất kì phần mềm giải nén file (winrar, winzip, 7zip ) nào để lấy ra nội dung của file nén.

ZipUtil_2

Song song với việc kiểm tra chức năng nén file, chúng ta cũng tạo một lớp khác để kiểm tra chức năng giải nén.

Test giải nén

TestExtraction.java


package com.wordpress.hautudu.ziptools;

import java.io.File;

public class TestExtraction {
	public static void main(String [] args){
		String zipFilePath = "D:/ZipDemo/MyZip.zip";
		String extractDestination = "D:/ZipDemo";
		
		if(ZipUtil.extract(new File(zipFilePath), extractDestination)){
			System.out.println("Extracted successfully to "+extractDestination);
		}else{
			System.out.println("Fail to extract files!");
		}
	}
}

Bây giờ hãy chỉ để lại file nén lúc trước, xóa các file còn lại trong cùng thư mục và chạy chương trình trên. Chương trình chạy thành công sẽ hiện ra message “Extracted successfully to D:/ZipDemo” và 3 file sẽ được trích ra từ nội dung file nén.

ZipUtil_3

By Coder Sơn Trang Posted in Java Core Tagged

3 comments on “Nén và giải nén file với Java IO

  1. ban cho minh hoi cho nay
    for(File f : sourceFiles) trong public static boolean compress(List sourceFiles, String zipFile, String zipDestination), o day sourceFiles la kieu list làm sao mà File f : sourceFiles đúng được bạn , mình đã thử và bị báo lỗi , mình có cần ép kiểu không bạn

    Số lượt thích

Trả lời

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Đăng xuất /  Thay đổi )

Google photo

Bạn đang bình luận bằng tài khoản Google Đăng xuất /  Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Đăng xuất /  Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Đăng xuất /  Thay đổi )

Connecting to %s