Trang chủHướng dẫnHướng dẫn chi tiết cách nén file Java và thư mục thành ZIP
Java

Hướng dẫn chi tiết cách nén file Java và thư mục thành ZIP

CyStack blog 3 phút để đọc
CyStack blog04/09/2025
Locker Avatar

Bao Tran

Web Developer

Locker logo social
Reading Time: 3 minutes

Hôm nay chúng ta sẽ tìm hiểu về cách nén file Java. Chúng ta cũng sẽ thử nén một thư mục và tạo file ZIP bằng chương trình Java.

 cách nén file Java

File ZIP trong Java

java.util.zip.ZipOutputStream có thể được sử dụng để nén một file sang định dạng ZIP.

Vì một file ZIP có thể chứa nhiều mục (entries), nên ZipOutputStream sử dụng java.util.zip.ZipEntry để biểu diễn từng mục trong file ZIP.

Việc tạo một tệp zip cho một tệp duy nhất rất dễ dàng, chúng ta cần tạo một đối tượng ZipOutputStream từ đối tượng FileOutputStream của tệp đích. Sau đó, chúng ta thêm một ZipEntry mới vào ZipOutputStream và sử dụng FileInputStream để đọc tệp nguồn vào đối tượng ZipOutputStream. Sau khi ghi xong, chúng ta cần đóng ZipEntry và giải phóng tất cả tài nguyên.

Java Zip Folder

Nén một thư mục thì hơi phức tạp hơn một chút. Đầu tiên, chúng ta cần lấy danh sách các file với đường dẫn tuyệt đối. Sau đó, xử lý từng file một cách riêng biệt. Với mỗi file, chúng ta phải thêm một ZipEntry và sử dụng FileInputStream để đọc nội dung file nguồn rồi ghi vào ZipEntry tương ứng của file đó.

Ví dụ Java Zip

Dưới đây là chương trình Java minh họa cách nén một file đơn lẻ hoặc nén cả một thư mục trong Java.

package com.journaldev.files;

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

public class ZipFiles {
    
    List<String> filesListInDir = new ArrayList<String>();

    public static void main(String[] args) {
        File file = new File("/Users/pankaj/sitemap.xml");
        String zipFileName = "/Users/pankaj/sitemap.zip";
        
        File dir = new File("/Users/pankaj/tmp");
        String zipDirName = "/Users/pankaj/tmp.zip";
        
        zipSingleFile(file, zipFileName);
        
        ZipFiles zipFiles = new ZipFiles();
        zipFiles.zipDirectory(dir, zipDirName);
    }

    /**
     * This method zips the directory
     * @param dir
     * @param zipDirName
     */
    private void zipDirectory(File dir, String zipDirName) {
        try {
            populateFilesList(dir);
            //now zip files one by one
            //create ZipOutputStream to write to the zip file
            FileOutputStream fos = new FileOutputStream(zipDirName);
            ZipOutputStream zos = new ZipOutputStream(fos);
            for(String filePath : filesListInDir){
                System.out.println("Zipping "+filePath);
                //for ZipEntry we need to keep only relative file path, so we used substring on absolute path
                ZipEntry ze = new ZipEntry(filePath.substring(dir.getAbsolutePath().length()+1, filePath.length()));
                zos.putNextEntry(ze);
                //read the file and write to ZipOutputStream
                FileInputStream fis = new FileInputStream(filePath);
                byte[] buffer = new byte[1024];
                int len;
                while ((len = fis.read(buffer)) > 0) {
                    zos.write(buffer, 0, len);
                }
                zos.closeEntry();
                fis.close();
            }
            zos.close();
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    /**
     * This method populates all the files in a directory to a List
     * @param dir
     * @throws IOException
     */
    private void populateFilesList(File dir) throws IOException {
        File[] files = dir.listFiles();
        for(File file : files){
            if(file.isFile()) filesListInDir.add(file.getAbsolutePath());
            else populateFilesList(file);
        }
    }

    /**
     * This method compresses the single file to zip format
     * @param file
     * @param zipFileName
     */
    private static void zipSingleFile(File file, String zipFileName) {
        try {
            //create ZipOutputStream to write to the zip file
            FileOutputStream fos = new FileOutputStream(zipFileName);
            ZipOutputStream zos = new ZipOutputStream(fos);
            //add a new Zip Entry to the ZipOutputStream
            ZipEntry ze = new ZipEntry(file.getName());
            zos.putNextEntry(ze);
            //read the file and write to ZipOutputStream
            FileInputStream fis = new FileInputStream(file);
            byte[] buffer = new byte[1024];
            int len;
            while ((len = fis.read(buffer)) > 0) {
                zos.write(buffer, 0, len);
            }
            
            //Close the zip entry to write to zip file
            zos.closeEntry();
            //Close resources
            zos.close();
            fis.close();
            fos.close();
            System.out.println(file.getCanonicalPath()+" is zipped to "+zipFileName);
            
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

Đầu ra của chương trình ví dụ java zip ở trên là:

/Users/pankaj/sitemap.xml is zipped to /Users/pankaj/sitemap.zip
Zipping /Users/pankaj/tmp/.DS_Store
Zipping /Users/pankaj/tmp/data/data.dat
Zipping /Users/pankaj/tmp/data/data.xml
Zipping /Users/pankaj/tmp/data/xmls/project.xml
Zipping /Users/pankaj/tmp/data/xmls/web.xml
Zipping /Users/pankaj/tmp/data.Xml
Zipping /Users/pankaj/tmp/DB.xml
Zipping /Users/pankaj/tmp/item.XML
Zipping /Users/pankaj/tmp/item.xsd
Zipping /Users/pankaj/tmp/ms/data.txt
Zipping /Users/pankaj/tmp/ms/project.doc

Lưu ý rằng khi ghi log các file vào tệp zip trong thư mục, mình đang in ra đường dẫn tuyệt đối. Tuy nhiên, khi thêm ZipEntry, mình lại sử dụng đường dẫn tương đối tính từ thư mục gốc. Điều này giúp khi giải nén (unzip), chương trình sẽ tái tạo lại đúng cấu trúc thư mục ban đầu. Và đó là toàn bộ ví dụ về nén file trong Java.

0 Bình luận

Đăng nhập để thảo luận

Chuyên mục Hướng dẫn

Tổng hợp các bài viết hướng dẫn, nghiên cứu và phân tích chi tiết về kỹ thuật, các xu hướng công nghệ mới nhất dành cho lập trình viên.

Đăng ký nhận bản tin của chúng tôi

Hãy trở thành người nhận được các nội dung hữu ích của CyStack sớm nhất

Xem chính sách của chúng tôi Chính sách bảo mật.

Đăng ký nhận Newsletter

Nhận các nội dung hữu ích mới nhất